属性名的简写
//ES5
let a = 1;
let b = 2;
let obj = {
a:a,
b:b
}
// ES6
let obj = {a,b}
属性名的表达式
// js 定义对象属性两个方法
// 方法一
obj.a = 2;
// 方法二
obj['a'+'bc'] = 123;
// 方法一是直接用属性名进行赋值的、方法二是利用表达式进行对 对象的属性名进行赋值。表达式一定要写在[]里面
// 注意 属性名表达式与简洁表示法不能同时使用 否则会报错
Object.is() 方法
ES5比较两个值是否相等,只有两个运算符相等运算符 '==' 和 严格运算符 '==='。两者都有缺陷,前者会自动转换数据类型。后者NaN与NaN、+0与-0 不相等。Object.is() 解决了 严格运算符这两个不足。
Object.is('foo','foo'); // true
Object.is(NaN,NaN); // true
Object.is(+0,-0); // false
console.log(NaN === NaN); // false
console,log(+0===-0); // true
在ES5 中可以这样部署
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
}
})
Object.assign()
基本用法
Object.assign() 方法用于将源对象的所有可枚举对象复制到目标对象。
var target ={a:1};
var s1 = {b:2};
var s2 = {c:3};
// 第一个参数是目标对象 其余的都是源对象 如果目标对象与源对象 源对象与源对象之间属性名有重合的 后面就会把前面的覆盖。
console.log(Object.assign(target,s1,s2));// {a:1,b:2,c:3}
// 由于 undefined 和 null无法转换成对象所以就会报错。
Object.assgin(undefined) // 报错
Object.assgin(null) // 报错
// 如果非对象参数出现在源对象的位置,那么处理规则就会不同,会把数据转换为对象,如果不能转换为对象就会跳过。所以undefined,null就不会报错,
console.log(Object.assign({},'a'));// {'0':'a'}
// 其他类型(数值,布尔值,字符串) 不再首参数也不会报错。但是除了字符串会以会以数组的形式复制到目标对象,其他的不会出现效果
let v1 = 'abc';
let v2 = true;
let v3 = 10;
console.log({},v1,v2,v3);// {'0':'a','1':'b','c':'2'}
// Object.assign() 复制是有限的 只复制源对象自身的属性(不包括继承属性) 不可复制不可枚举的属性。
Object.assign({b:'c'},{
Object.defineProperty({},a{
value:'aa',
enumerable:false, // 是否可枚举
})
})// {b:'c'}
// 因为Object.assign() 不可复制不可枚举的属性
Object.assign()是浅拷贝
如果某个源对象的值是引用型数据,那么目标对象复制到的是这个引用型数据的内存地址。
// Object.assign() 能处理数组 但是会把数据当作对象处理
Object.assign([1,2,3],[4,5]);// [4,5,3]
常见用途
为对象添加属性
class Ponit{
constructor(x,y){
Object.assign(this,{x,y})
}
}
// 通过assign的方法把 x y 属性添加到 Point实例对象中
克隆对象
// 对obj对象进行浅拷贝 不能赋值obj继承的属性和不可枚举的属性
Object.assign({},obj);
合并对象
Object.assign(obj1,obj2,obj3);// 会合并一个新的对象 如有属性名相同的值 后面的会覆盖前面的值
ES6属性的遍历
for..in..
for..in.. 循环遍历对象自身和继承的可枚举的属性
Object.keys()
Object.keys()返回一个数组,包括对象自身的(不含继承的)所有可枚举的属性
Object.getOwnPropertyNames()
返回一个数组包括对象的所有的属性(不含Symbol 但是包含不枚举属性)
Object.getOwnPropertySymbol()
返回一个数组,包含对象的所有属性包含Symbol
Reflect.ownKeys
返回一个数组,包含对象的所有属性无论是Symbol还是不可枚举的属性
Object.keys()
let obj = {a:1.b:2,c:3};
Object.keys(obj);// ['a','b','c']
Object.values()
Object.values(obj);// [1,2,3]
Object.entries()
Object.entries(obj);// [['a',1],['b':2],['c':3]]
对象的扩展运算符
let {x,y,...z} = {a:1,b:2,c:3,d:4};
x //1
y // 2
z // {c:3,d:4}
由于结构赋值要求等号左边是一个对象,所以如果等号右边是 undefined与null就会报错,因为他们不能转换为 对象
let {x,...y} = undefined // 报错
let {x,...y} = null // 报错
注意: 结构赋值不是最后一个参数,就会报错。
结构赋值时浅拷贝
合并对象
扩展运算符可用于合并两个对象
let ab = {...a,...b};
// 等同于
let ab = Object.assign({},a,b)
// 如果用户定义的属性放在扩展运算符后面,则扩展运算符内部的同名属性会覆盖
null传导运算符(可链操作符)
编程中,如果读取对象内部的某个属性,往往需要判断该对象是否存在。比如:要读取message.body.user.firstName 安全写法如下:
const firstName = (message && message.body && message.body.user&& message.body.user.firstName) || 'default'
// 引入 Null传导运算符后
const firstName = message?.body?.usere?.firstName
// 上面代码有三个?. 运算符 只要其中一个返回 null 或者 undefined 就不会继续执行