//ES5 对象 const getInfo=(id=1)=>{ //ajax... const name="cyy"; const age=18; return { name:name, age:age, say:function(){ console.log(this.name+this.age); } } } const cyy=getInfo(); //ES6 对象的简洁表示法 const getInfo2=(id=1)=>{ //ajax... const name="cyy"; const age=18; return { name,//会去找同名变量 age, say(){//方法可以省略冒号 console.log(this.name+this.age); } } } const cyy2=getInfo2();
属性名表达式
const cyy={ name:"cyy", age:18, "#^":"不规范的属性名要用单引号或者双引号" }
//ES6 const key="#^"; const cyy2={ name:"cyy2", age:18, [key]:"ES6使用[]" }
[ ]里可以有表达式
//ES6 const cyy2={ name:"cyy2", age:18, ["aa"+"bb"+"cc"]:"ES6使用[]" }
[ ] 里可以有模板字符串
//ES6 const key="str"; const cyy2={ name:"cyy2", age:18, [`${ key } 123`]:"ES6使用[]" }
扩展运算符(扩展运算符及新方法)
//复制对象 const obj1={ a:1, b:2 } let cobj1={...obj1};
使用扩展运算符复制对象属于浅拷贝(拷贝引用地址),而不是深拷贝(拷贝所有数据)
//扩展运算符拷贝,拷贝的是引用地址 const obj1={ a:1, b:2, c:{ d:11, f:22 } } let cobj1={...obj1}; console.log(cobj1.c.d);//11 cobj1.c.d=111; console.log(cobj1.c.d);//111 console.log(obj1.c.d);//111
合并对象
//合并对象,属性相同时后面的会覆盖前面的 const obj1={ a:1, b:2, c:{ d:11, f:22 } } const obj2={ a:3, g:4 } const nobj={ ...obj1, ...obj2 }
合并对象也是浅拷贝,拷贝的是引用地址:
//合并对象 const obj1={ a:1, b:2, c:{ d:11, f:22 } } const obj2={ a:3, g:4 } const nobj={ ...obj1, ...obj2 } //浅拷贝 nobj.c.d=111; console.log(obj1.c.d);
新的方法:Object.is()
console.log(+0===-0);//true console.log(Object.is(+0,-0));//false console.log(NaN==NaN);//false console.log(Object.is(NaN,NaN));//true
Object.assign() 赋值或合并对象
属性相同时后面的会覆盖前面的
也是属于浅拷贝
//对象合并,相同属性后面的覆盖前面的 let obj=Object.assign({a:1},{b:2,c:3},{c:4});//{a: 1, b: 2, c: 4} console.log(obj); let obj1={ a:1, b:{ b1:11, b2:22 } } let obj2={ c:3, d:4 } let obj3=Object.assign({},obj1,obj2); console.log(obj3);//{a: 1, b: {…}, c: 3, d: 4} //浅拷贝 obj3.b.b1=111; console.log(obj1.b.b1);//111
Object.keys()
Object.values()
Object.entries()
let obj={ a:1, b:{ b1:11, b2:22 } } //获取对象的属性名组成的数值 console.log(Object.keys(obj));//["a", "b"] //获取对象的属性值组成的数值 console.log(Object.values(obj));//[1, {…}] //获取对象的属性名和属性值作为键值对,组成的数值 console.log(Object.entries(obj));//[Array(2), Array(2)]
for of 遍历对象
let obj={ a:1, b:{ b1:11, b2:22 } } //for of 遍历得到每一个属性名 for(let key of Object.keys(obj)){ console.log(key); } //for of 遍历,结构赋值得到每一个属性名和属性值 for(let [k,v] of Object.entries(obj)){ console.log(k,v); }
Rest 解构赋值不会拷贝继承自原型对象的属性
let obj1={a:1}; let obj2={b:2}; obj2.__proto__=obj1; let obj3={...obj2};
__proto__
对象的原型,建议实际开发中尽量不要用到
const obj={a:1};
Object.setPrototypeOf 修改对象的原型,性能比较低,不建议使用
const obj1={a:1}; const obj2={b:2}; const obj=Object.create(obj1);//以obj1为原型创建obj console.log(obj.__proto__);//obj的原型 Object.setPrototypeOf(obj,obj2);//将obj的原型改为obj2 console.log(obj.__proto__);//obj的原型
Object.getPrototypeOf() 获取对象的原型
const obj1={a:1}; const obj=Object.create(obj1);//以obj1为原型创建obj console.log(obj.__proto__);//obj的原型 console.log(Object.getPrototypeOf(obj));//obj的原型 console.log(obj.__proto__===Object.getPrototypeOf(obj));//true
super 关键字,可以访问到对象的原型,访问到原型对象上的属性和方法
const obj1={myname:"cyy"}; const obj={ say(){ console.log(this.myname); } } Object.setPrototypeOf(obj,obj1);//修改obj的原型为obj1 obj.say(); const cobj1={name:"cyy"}; const cobj={ say(){ console.log(`${ super.name }`);//通过super访问原型对象 } } Object.setPrototypeOf(cobj,cobj1);//修改obj的原型为obj1 cobj.say();
只有对象的简写方式,可以用super;箭头函数或者原来的语法,都不可以
//对象简写,可以用super const cobj1={name:"cyy"}; const cobj={ say(){ console.log(`${ super.name }`); } } Object.setPrototypeOf(cobj,cobj1); cobj.say();//cyy //ES5,不能用super const nobj1={name:"cyy"}; const nobj={ say:function(){ console.log(`${ super.name }`); } } Object.setPrototypeOf(nobj,nobj1); nobj.say();//报错 //箭头函数,不能用super const vobj1={name:"cyy"}; const vobj={ say:()=>{ console.log(`${ super.name }`); } } Object.setPrototypeOf(vobj,vobj1); vobj.say();//报错