美文网首页Web前端之路
js 对象的遍历与复制

js 对象的遍历与复制

作者: 前端人 | 来源:发表于2019-08-11 17:50 被阅读47次

    对象属性遍历,就是要搞清楚 哪些属性可以遍历,哪些属性不能遍历。

    对象复制 就是要搞清楚 哪些属性可以复制,哪些属性不能复制。

    那么首先要了解的知识 是属性分类,不同类型的属性有不同的行为。

    属性的分类

    直接上图了

    不了解类别的可以看我下面的代码

    -------------代码开始

    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交流

    相关文章

      网友评论

        本文标题:js 对象的遍历与复制

        本文链接:https://www.haomeiwen.com/subject/xvesjctx.html