//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 ...
//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 關鍵字,可以訪問到對象的原型,訪問到原型對象上的屬性和方法
使用this也是可以訪問到原型上的屬性的。在本代碼中,效果類似於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();//報錯