这篇文章是我学习了《你不知道的JavaScript》下卷 ES6 新增API Object部分,然后摘抄与整理所学到的四种 Object 函数。
1. 静态函数 Object.is(..)
静态函数Object.is(..)执行比===比较更严格的值比较。
Object.is(..)调用底层 SameValue 算法。SameValue 算法基本上和===严格相等比较算法一样,但有两个重要的区别。
考虑:
var x = NaN, y = 0, z = -0;
x === x; // false
y === z; // true
Object.is( x, x ); // true
Object.is( y, z ); // false
因此,应该继续使用===进行严格相等比较,不应该把Object.is(..)当作严格相等运算符的替代。但是,如果需要严格识别 NaN 和 -0 值,那么应该选择Object.is(..)。
2. 静态函数 Object.getOwnPropertySymbols(..)
ES6中新增了基本值类型 Symbol,而 Symbol 很可能会成为对象最常用的特殊(元)属性。所以引入了工具Object.getOwnPropertySymbols(..),他直接从对象上取得所有的符号属性:
var o = {
foo: "42",
[ Symbol( "bar" ) ]: "hello world",
baz: true
};
Object.getOwnPropertySymbols( o ); // [ Symbol(bar) ]
3. 静态函数 Object.setPrototypeOf(..)
工具Object.setPrototypeOf(..)设置对象的[[Prototype]]用于行为委托。考虑:
var o1 = {
foo() { console.log( "foo" ); }
};
var o2 = {
// .. o2的定义 ..
};
Object.setPrototypeOf( o2, o1 );
// 委托给o1.foo()
o2.foo(); // foo
也可以:
var o1 ={
foo() { console.log( "foo" ); }
};
var o2 = Object.setPrototypeOf( {
// .. o2的定义 ..
}, o1 );
// 委托给o1.foo()
o2.foo(); // foo
前面两段代码中,o2 和 o1 的关系都出现在 o2 定义的结尾处。更通俗的说, o2 和 o1 的关系在 o2 的定义上指定,就像类一样,也和字面值对象中的__proto__一样。
4. 静态函数 Object.assign(..)
很多 JavaScript 库/框架提供了用于把一个对象的属性复制/混合到另一个对象中的工具。这些工具之间有各种细微的区别,比如是否忽略值为 undefined 的属性。
ES6 新增了 Object.assign(..),这是这些算法的简化版本。第一个参数是 target,其他传入的参数都是源,他们将按照列出的顺序依次被处理。对于每一个源来说,它的可枚举和自己拥有的(即不是“继承来的”)键值,包括 Symbol 都会通过简单 = 赋值被复制。Object.assign(..)返回目标对象。
考虑这个对象设定:
var target = {},
o1 = { a: 1 }, o2 = { b: 2 },
o3 = { c: 3 }, o4 = { d: 4 };
// 设定只读属性
Object.defineProperty( o3, "e", {
value: 5,
enumerable: true,
writable: false,
configurable: false
} );
// 设定不可枚举属性
Object.defineProperty( o3, "f", {
value: 6,
enumerable: false
} );
o3[ Symbol( "g" ) ] = 7;
// 设定不可枚举符号
Object.defineProperty( o3, Symbol( "h" ), {
value: 8,
enumerable: false
} );
Object.setPrototypeOf( o3, o4 );
只有属性 a、b、c、e 以及 Symbol("g") 会被复制到 target 中:
Object.assign( target, o1, o2, o3 );
target.a; // 1
target.b; // 2
target.c; // 3
Object.getOwnPropertyDescriptor( target, "e" );
// { value: 5, writable: true, enumerable: true, configurable: true }
Object.getOwnPropertySymbols( target );
// [Symbol("g")]
复制过程会忽略属性 d、f 和 Symbol("h");不可枚举的属性和非自有的属性都会被排除在复制过程之外。另外,e 作为一个普通属性被复制,而不是作为只读属性复制。
在前一节中,展示了使用 setPrototypeOf(..) 设定对象 o2 和 o1 之间的 [[Prototype]] 关系。还有另外一种应用了 Object.assign(..) 的形式:
var o1 = {
foo() { console.log( "foo" ); }
};
var o2 = Object.assign(
Object.create( o1 ),
{
// .. o2的定义 ..
}
);
// 委托给o1.foo()
o2.foo(); // foo
完