Object.assign 在 Javascript 中复制的属性中缺少基元

Primitives missing from properties copied by Object.assign in Javascript

我有一个关于 Object.assign() 的问题。

const v1 = 'abc';
const v2 = true;
const v3 = 10;
const v4 = Symbol('foo');

//Primitives will be wrapped to objects
const obj = Object.assign({}, v1, null, v2, undefined, v3, v4); 
// Primitives will be wrapped, null and undefined will be ignored.
// Note, only string wrappers can have own enumerable properties.
console.log(obj); // { "0": "a", "1": "b", "2": "c" }

输出只是{ "0": "a", "1": "b", "2": "c" }。我想这是 "abc" 被包装到一个对象的结果。

注释说 nullundefined 被忽略,因此它们不在输出中。

但是 v2v3v4 呢?它们不存在于输出中,所以我想知道如果包装到对象中它们会变成什么。

你能解释一下为什么输出中只有 { "0": "a", "1": "b", "2": "c" } 吗?我猜这是因为 true10 以及 Symbol('foo') 的包装器没有自己的可枚举属性。我在正确的轨道上吗?

谢谢。

是的,你的假设是正确的。字符串具有可枚举的属性,而布尔值、数字和符号则没有。根据MDN:

The Object.assign() method only copies enumerable and own properties from a source object to a target object.

Object.assign() 将所有可枚举自身属性的值从一个或多个源对象复制到目标对象。例如:

const sourceObject = {
    v1: 'abc',
    v2: true,
    v3: 10
};

const sourceObject2 = {
    b1: 'def',
    b2: false
};

const obj = Object.assign(sourceObject, sourceObject2); 
console.log(obj);

But what of v2, v3, and v4? They are not present in the output so I wonder what they become if wrapped to objects.

各自类型的实例,BooleanNumberSymbol

只有这些类型没有可以分配的可枚举属性,只有继承的方法。

看看这个:

var obj = {};
obj.test = 1;
Object.defineProperty(obj, "foo", {
  enumerable: false,
  value: 13
});

console.log("obj.foo", obj.foo);
console.log("assigned", Object.assign({}, obj)); // foo is not enumerable

var obj2 = Object.create({ bar: 42 });
obj2.test = 2;
console.log("obj2.bar", obj2.bar);
console.log("assigned", Object.assign({}, obj2)); // bar is inherited, not own

这是一个基于 Thomas 片段的示例。

//propertyIsEnumerable()

var obj = {};
obj.test = 1;
Object.defineProperty(obj, "foo", {
  enumerable: false,
  value: 13
});

console.log(obj.propertyIsEnumerable('foo'));
//console.log("obj.foo", obj.foo);
//console.log("assigned", Object.assign({}, obj)); // foo is not enumerable

var obj2 = Object.create({ bar: 42 });
obj2.test = 2;
//console.log("obj2.bar", obj2.bar);
//console.log("assigned", Object.assign({}, obj2)); // bar is inherited, not own

console.log(obj2.propertyIsEnumerable('bar'));

如您所见,属性 'foo' 和 'bar' 都不可枚举,因此它们都输出 false.

正如 Thomas 所提到的,'foo' 不可枚举只是因为描述符将其定义为 enumerable: false,并且 'bar' 不是 obj2 的 属性 而是继承的,因此它是也不可枚举。