object.is()判断两个值是否相等
- es5中通过==和===判断两个值是否相等,但是却无法判断NaN、-0、+0; NaN不等于自身,-0等于+0;
Object.is(NaN, NaN); //true;Object.is(-0, +0); //false
- es5可以通过一下代码来部署Object.is:
Object.defineProperty(Object, 'is', { value: function(x, y) { if (x === y) { // 针对+0 不等于 -0的情况 return x !== 0 || 1 / x === 1 / y; } // 针对NaN的情况 return x !== x && y !== y; }, configurable: true, enumerable: false, writable: true});
Object.assign(target,...source1)
- 该方法用于合并对象,将源对象(source)的可枚举属性加到target上
- 不可枚举的属性和源对象的继承属性都是不会复制到目标对象上
- 如果target与源对象(source)有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
- 关于参数,其他基础类型的数据只有字符串的包装类对象会产生克枚举的属性
- 注意:浅拷贝
Object.assign({name:'zhan'},'test')// {0: "t", 1: "e", 2: "s", 3: "t", name: "zhan"}
- 数组处理:
Object.assign([1, 2, 3], [4, 5])// [4, 5, 3]
- 克隆对象:
function cloneObj (obj) {return Object.assign({}, obj);}// 如果要保持克隆的对象的继承性function cloneObj (obj) {let proto = Object.getPrototypeOf(obj);return Object.assign(Object.creat(proto), obj);}
- 设置默认的属性
const DEFAULTS = { logLevel: 0, outputFormat: 'html'};function processContent(options) { options = Object.assign({}, DEFAULTS, options); console.log(options); // ...}
- 取值函数的处理
// Object.assign只能进行值的复制,如果要复制的值是一个取值函数,那么将求值后再复制。// source对象的foo属性是一个取值函数,Object.assign不会复制这个取值函数,只会拿到值以后,将这个值复制过去const source = { get foo() { return 1 }};const target = {};Object.assign(target, source)
-
关于对象属性遍历:
-
for...in
- for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
-
Object.keys(obj)
- Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
-
Object.getOwnPropertyNames(obj)
- Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
-
Object.getOwnPropertySymbols(obj)
- Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。
-
Reflect.ownKeys(obj)
- Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
-
-
以上的 5 种方法遍历对象的键名,都遵守同样的属性遍历的次序规则。
- 首先遍历所有数值键,按照数值升序排列。
- 其次遍历所有字符串键,按照加入时间升序排列。
- 最后遍历所有 Symbol 键,按照加入时间升序排列。
Object.getOwnPropertyDescriptors()
- ES2017 引入了Object.getOwnPropertyDescriptors方法,返回指定对象所有自身属性(非继承属性)的描述对象
- Object.getOwnPropertyDescriptor(obj,prop) 获取目标对象的某个自身属性(非继承属性)的描述对象
- 主要是为了解决Object.assign()无法正确拷贝get属性和set属性的问题。
- 使用见下例子:
const source = { set foo(value) { console.log(value); }};const target1 = {};Object.assign(target1, source);Object.getOwnPropertyDescriptor(target1, 'foo')// { value: undefined,// writable: true,// enumerable: true,// configurable: true }//如果采用Object.defineProperties()和Object.getOwnPropertyDescriptors()将源对象的属性(非继承)添加到目标对象上Object.defineProperties(target1,Object.getOwnPropertyDescriptors(source))Object.getOwnPropertyDescriptor(target1, 'foo')// { get: undefined, // set: [Function: set foo], // enumerable: true, // configurable: true }
Object.create(proto [...prop]); es5
-
proto:创建对象的原型
-
第二参数是对象的描述对象
-
结合Object.create复制对象,且保持继承性,见代码:
let obj = {name: 'zhan'}let obj1 = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj))// 第二种:let obj1 = Object.assign(Object.create(Object.getPrototypeOf(obj)),obj)
Object.setPrototypeOf(object, prototype)(写操作)
- 设置目标对象的原型
Object.getPrototypeOf(obj)(读操作)
- 获取目标对象的原型
super关键字
- 指向当前对象的原型对象
const proto = { foo: 'hello'};const obj = { foo: 'world', find() { return super.foo; }};Object.setPrototypeOf(obj, proto);obj.find() // hello//super.foo等同于Object.getPrototypeOf(this).foo(属性)或Object.getPrototypeOf(this).foo.call(this)(方法)。
- super关键字表示原型对象时,只能用在对象的方法之中,只有对象方法的简写法可以让 JavaScript 引擎确认,定义的是对象的方法。
// 报错const obj = { foo: () => super.foo}// 报错const obj = { foo: function () { return super.foo }}//只有如下对象方法的简写才正确const obj = { foo () { return super.foo }}
Object.keys(),Object.values(),Object.entries()
- 都忽略对象的继承属性
- Object.keys() 返回对象属性的键值对名数组
- Object.values() 返回对象属性的键值对值数组
- Object.entries() 返回对象属性的键值对数组
对象扩展运算符...
- 结合结构赋值
- 注意:解构赋值必须是最后一个参数
- 解构赋值的拷贝是浅拷贝
- 扩展运算符的解构赋值,不能复制继承自原型对象的属性
例子1:let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };x // 1y // 2z // { a: 3, b: 4 }例子2:let { ...x, y, z } = obj; // 句法错误let { x, ...y, ...z } = obj; // 句法错误例子3:let obj = { a: { b: 1 } };let { ...x } = obj;obj.a.b = 2;x.a.b // 2例子4:let o1 = { a: 1 };let o2 = { b: 2 };Object.setPrototypeOf(o2,o1)// o2.__proto__ = o1;let { ...o3 } = o2;o3 // { b: 2 }o3.a // undefined