一、对象基础部分用法点击这里带你去
二、Object.is()注意细节
在ES5中比较两个值是否相等,只有两个运算符:相等运算符和严格相等运算符。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于直身,以及+0等于-0
console.log(NaN ===NaN); //false
console.log(+0 ===-0); //true
ES6使用Object.is()来解决该问题,与严格相等运算符的行为基本一致。不同的是:NaN等于本身,+0不等于-0
console.log(Object.is(NaN,NaN)); //true
console.log(Object.is()+0,-0); //false
三、Object.assign()注意细节
注意一:如果只有一个参数时,Object.assign()会直接返回该参数。
var obj={a:1};
Object.assign(obj) === obj; //true
如果该参数不是对象,则会先转换为对象,然后返回。
typeof Object.assign(2); //object
console.log(Object.assign(2)); //Number{2}
因为undefined和null不能转换为对象,如果将其作为参数会报错
console.log(Object.assign(undefined));//报错
console.loh(Object.assign(null));//报错
其他类型的值(字符串,数值,布尔值)不在首参数也不会报错。但,除了字符串会以数组形式复制到目标对象,其他值都不会产生效果。
var v1="abc";
var v2=true;
var v3=10;
var obj=Object.assign({},v1,v2,v3);
console.log(obj); //{"0":"a","1":"b","2":c}
这是因为只有字符串的包装对象会产生可枚举属性。
Object(true);//{[[PrimitiveValue]]:true}
Object(10);//{[[PrimitiveValue]]:10}
Object('abc');
可以看到它们的原始值都包含在包装对象的内部属性[[PrimitiveValue]]上面,这个属性是不会被Object.assign()复制的。只有字符串的包装对象会产生可枚举的实义属性,那些属性则会被拷贝。
属性名为Symbol值的属性也会被Object.assign()复制
Object.assign({a:'b'},{[Symbol('c')]:'d'}); //{a:'b',Symbol(c):'d'}
总结:Object.assign()复制的属性是有限制的,只复制源对象的自身属性(不复制继承属性),也不复杂不可枚举的属性(enumerable:false)。
注意二:Object.assign()实现的是浅拷贝,如果源对象某个属性的值是对象,那么目标对象复制得到的是这对象的引用。
let target = {};
let source = {a: 1, b: {c: 2, d: 3}};
Object.assign(target, source);
target.a = 5;
target.b.c = 9;
console.log(target) // {a: 5, b: {c: 9, d: 3}}
console.log(source) // {a: 1, b: {c: 9, d: 3}}
对于出现嵌套对象,遇到同名属性,Object.assgin的处理方法是替换而不是添加。
var target={a:{b:'c',d:'e'}};
var source={a:{b:'hello'}};
Object.assign(target,source); //{a:{b:'hello'}}
target对象的a属性被source对象的a属性整个替换掉,而不是得到{a:{b:‘hello’,d:‘e’}}
注意三:Object.assign()可以用来处理数组,但是会将数组视为对象来处理。
Object.assign([1,2,3],[4,5]); //[4,5,3]
上面代码中,Object.assign()把数组视为属性名为0、1、2的对象,因此目标数组的0属性4覆盖了原数组的0号属性1。
四、属性的可枚举性
对象的每一个属性都具有一个描述对象,用于控制该属性的行为。
let obj={foo:123};
Object.getOwnPropertyDescriptor(obj,'foo');
因为enumerable属性(可枚举性)的值为false,故这个属性值在某些操作下会被忽略。
这些操作指的是:在ES5中
- for…in循环:只遍历对象自身的和继承的可枚举属性
- Object.keys():返回对象自身的所有可枚举属性的键名
- JSON.stringify():只串行化对象自身的可枚举属性
在ES6增加了一个操作Object.assign(),会忽略enumerable=false,只复制对象自身的可枚举属性。
注意:ES6规定,所有Class的原型的方法都是不可枚举的。
Object.getOwnPropertyDescriptor(class {foo(){....}},'foo').enumerable; //false
五、属性的遍历
- for…in =>循环遍历对象自身的和继承的可枚举属性(不包含Symbol属性)
- Object.keys(obj) =>返回一个数组,包含对象自身的(不含继承)所有可枚举属性(不含Symbol属性)
- Object.getOwnPropertyNames(obj) =>返回一个数组,包含对象自身的所有属性(不含Symbol属性,包含不可枚举属性)
- Object.getOwnPropertySymbols(obj) =>返回一个数组,包含对象自身的所有Symbol属性
- Refected.ownKeys(obj) =>返回一个数组,包含对象自身的所有属性,不管属性名是Symbol还是字符串,也不管是否可枚举