对象属性遍历, 就是要搞清楚 哪些属性可以遍历, 哪些属性不能遍历.
对象复制 就是要搞清楚 哪些属性可以复制, 哪些属性不能复制.
那么首先要了解的知识 是属性分类, 不同类型的属性有不同的行为.
属性的分类
直接上图了
不了解类别的可以看我下面的代码
------------- 代码开始
- 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 交流
来源: http://www.jianshu.com/p/3099f060503c