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"
被包装到一个对象的结果。
注释说 null
和 undefined
被忽略,因此它们不在输出中。
但是 v2
、v3
和 v4
呢?它们不存在于输出中,所以我想知道如果包装到对象中它们会变成什么。
你能解释一下为什么输出中只有 { "0": "a", "1": "b", "2": "c" }
吗?我猜这是因为 true
和 10
以及 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.
各自类型的实例,Boolean
、Number
和 Symbol
。
只有这些类型没有可以分配的可枚举属性,只有继承的方法。
看看这个:
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 的 属性 而是继承的,因此它是也不可枚举。
我有一个关于 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"
被包装到一个对象的结果。
注释说 null
和 undefined
被忽略,因此它们不在输出中。
但是 v2
、v3
和 v4
呢?它们不存在于输出中,所以我想知道如果包装到对象中它们会变成什么。
你能解释一下为什么输出中只有 { "0": "a", "1": "b", "2": "c" }
吗?我猜这是因为 true
和 10
以及 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.
各自类型的实例,Boolean
、Number
和 Symbol
。
只有这些类型没有可以分配的可枚举属性,只有继承的方法。
看看这个:
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 的 属性 而是继承的,因此它是也不可枚举。