對象屬性遍歷,就是要搞清楚 哪些屬性可以遍歷,哪些屬性不能遍歷。
對象複製 就是要搞清楚 哪些屬性可以複製,哪些屬性不能複製。
那麼首先要了解的知識 是屬性分類,不同類型的屬性有不同的行爲。
屬性的分類
直接上圖了
不瞭解類別的可以看我下面的代碼
-------------代碼開始
var sym = Symbol('sym');
var sym2 = Symbol('sym2');
var testObj = {
a: 1,//數據屬性
b: 2,
[Symbol('symbol屬性')]: 'symbol屬性',//symbol屬性
fun: function () { return this.a; },//函數屬性
get Cun() { //存取器屬性
return 0;
},
set Cun(val) {
this.a = val;
}
}
testObj[sym] = 'symbool';
//獲取數據屬性的特性描述符
let da = Object.getOwnPropertyDescriptor(testObj, 'a');
console.log('da', da)
let fa = Object.getOwnPropertyDescriptor(testObj, 'fun');
console.log('fa', fa)
//獲取存取器屬性的特性描述符
let Cun = Object.getOwnPropertyDescriptor(testObj, 'Cun');
console.log('Cun', Cun)
let symb = Object.getOwnPropertyDescriptor(testObj, sym);
console.log('symb', symb)
-----------------複製這些代碼就能夠了解這些屬性類別了
執行後的圖如下
研究遍歷行爲
相關代碼
var sym = Symbol('不可枚舉的symbol屬性');
var symCun = Symbol('存取的symbol屬性');
var sym2 = Symbol('sym2');
var testObj = {
a: 1,
b: 2,
[Symbol('testObj')]: 'testObj',
fun: function () { return this.a; },
get Cun() {
return 0;
},
set Cun(val) {
this.a = val;
},
get [symCun]() {
return '存取的symbol屬性';
}
}
testObj[sym] = 'symbool';
Object.defineProperty(testObj, sym, {
enumerable: false
})
var protoObj = {
a1: 1,
b2: 2,
fun2: function () { return this.a; },
set Cun2(val) {
this.a = val;
}
}
protoObj[sym2] = 'symbool2';
Object.setPrototypeOf(testObj, protoObj);
console.log('for in ------------')
for (const item in testObj) {
console.log(item)
}
console.log('Object.keys ------------')
for (const item of Object.keys(testObj)) {
console.log(item)
}
console.log(' Object.getOwnPropertyNames ------------')
for (const item of Object.getOwnPropertyNames(testObj)) {
console.log(item)
}
console.log(' Object.getOwnPropertySymbols ------------')
for (const item of Object.getOwnPropertySymbols(testObj)) {
console.log(item)
}
console.log(testObj, testObj[symCun])
運行後的結果
複製行爲研究
結果直接上圖
相關研究代碼
var sym = Symbol('sym');
var sym2 = Symbol('sym2');
var deepObj = { deep: 'deep' };
var testObj = {
a: 1,//數據屬性
b: 2,
deepObj: deepObj,
[Symbol('testObj')]: 'testObj',//Symbol類型屬性
fun: function () { return this.a; },//函數屬性
get Cun() { //存取器屬性
console.log('讀取get描述符被執行')
return 0;
},
set Cun(val) {
this.a = val;
}
}
testObj[sym] = 'symbool';
Object.defineProperty(testObj, 'a', {
enumerable: true,
configurable: false,
writable: false,
value: 'John'
})
//b屬性被定義爲不可枚舉
Object.defineProperty(testObj, 'b', {
enumerable: false,
configurable: false,
writable: false,
value: 'John'
})
var protoObj = {
a1: 1,
b2: 2,
fun2: function () { return this.a; },
set Cun2(val) {
this.a = val;
}
}
protoObj[sym2] = 'symbool2';
Object.setPrototypeOf(testObj, protoObj);
console.log('原對象', testObj, Object.getOwnPropertyDescriptor(testObj, 'a'), testObj.deepObj === deepObj)
console.log('...擴展符的複製')
let copy1 = { ...testObj };
console.log(copy1, Object.getOwnPropertyDescriptor(copy1, 'a'), '引用對象是否相等', copy1.deepObj === deepObj);
console.log('Object.assign的複製');
copy1 = Object.assign({}, testObj);
console.log(copy1, Object.getOwnPropertyDescriptor(copy1, 'a'), '引用對象是否相等', copy1.deepObj === deepObj);
console.log('json化的複製');
copy1 = JSON.parse(JSON.stringify(testObj));
console.log(copy1, Object.getOwnPropertyDescriptor(copy1, 'a'), '引用對象是否相等' + copy1.deepObj === deepObj);
運行後結果
有疑問或其他意見的可以評論或qq交流 qq352169715 加我請備註js交流