美文网首页
JavaScript 中 给对象添加属性用 “=” 和 Obje

JavaScript 中 给对象添加属性用 “=” 和 Obje

作者: BGING | 来源:发表于2019-02-21 16:09 被阅读0次

    js 在赋值操作的时候很方便,不需要类型一致才能赋值,一个 “=” 就解决问题。但是也牵扯出问题,例如今天的例子用 “=” 给对象添加属性发生的事。

    如果两个对象 A 和 B , B 的 prototype 指向 A 。那么在给 B 增加属性时,就会出现下列三种情况。

    情况1:大多数情况

    let A = { name: 1 };
    let B = Object.create(A);
    B.name = 2
    console.log(A.name) // 1
    console.log(B.name) // 2
    

    情况2:如果 A 的 name 属性标记只读 writable: false ,并且是在严格模式下

    'use strict' // 这句话要写在代码最顶部
    let A = { name: 1 };
    Object.defineProperty(A, 'name', {
        writable: false,
        enumerable: true,
        configurable: true
    })
    let B = Object.create(A);
    B.name = 2
    console.log(A.name)
    console.log(B.name)
    // 直接抛出异常
    //  TypeError: Cannot assign to read only property 'name' of object '#<Object>'
    

    如果是在非严格模式下是不会抛出异常的。A & B的 name 都为 1

    情况3:如果 A 的属性有 get/set 方法了

    let A = {
        coun: 18,
        get age() {
            return this.coun
        },
        set age(o) {
            this.coun = o
        }
    };
    let B = Object.create(A);
    B.age = 2
    console.log(A.age)  // 18
    console.log(B.age) // 2
    console.log(Object.keys(B)) // ['coun']
    console.log(Object.keys(A)) // ['coun', 'age']
    

    这里会直接调用 A 的 set 方法,并且 age 属性也不会添加到 B 对象上
    我们可以使用 Object.defineProperty 来设置属性

    let A = {
        coun: 18,
        get age() {
            return this.coun
        },
        set age(o) {
            this.coun = o
        }
    };
    let B = Object.create(A);
    Object.defineProperty(B, 'age', {
        value: 2,
        writable: true,
        enumerable: true,
        configurable: true
    
    })
    console.log(A.age)
    console.log(B.age)
    console.log(Object.keys(B)) // ['age']
    console.log(Object.keys(A)) // ['coun', 'age']
    for (v in B) {
        console.log(v)
    }
    // age , coun
    

    这样 B 对象就把 age 属性添加进去了,还可以避免出现情况2 & 情况3,所以如果是自己写 get/set方法那么在赋值的时候就需要注意了。

    自己在写上面实例的时候遇到的问题o(╥﹏╥)o

    let A = {
        name: 2
    }
    Object.defineProperty(A, "name", {
        get: function () {
            return A.name;
        },
        set: function (val) {
            A.name = val
        },
        enumerable: true
    });
    
    console.log(A.name)
    // 直接死循环了
    // RangeError: Maximum call stack size exceeded
    
    -----
    
    let A = {
        name: 2
    }
    let para = 0
    Object.defineProperty(A, "name", {
        get: function () {
            return para;
        },
        set: function (val) {
            para = val
        },
        enumerable: true
    });
    
    console.log(A.name)
    // 这样就对了,你都在重写 get/set 方法了,你还引用,相当于自己调用自己,不就死了么
    

    Tip

    Object.keys() 可以获取当前对象的属性,for in 遍历包含原型链上的属性

    下一篇如何获取对象的属性...

    还在更新...

    相关文章

      网友评论

          本文标题:JavaScript 中 给对象添加属性用 “=” 和 Obje

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