对象属性遍历,就是要搞清楚 哪些属性可以遍历,哪些属性不能遍历。
对象复制 就是要搞清楚 哪些属性可以复制,哪些属性不能复制。
那么首先要了解的知识 是属性分类,不同类型的属性有不同的行为。
属性的分类
直接上图了
不了解类别的可以看我下面的代码
-------------代码开始
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交流
网友评论