Vue源码解析涉及知识--Object.defineProprty

一、 Object.defineProprty概念:

  Object.defineProperty()方法会直接在一个对象上定义一个新属性,
或者修改一个对象的现有属性,并返回此对象。

二、 语法:

Object.definePrototype(obj,prop,descriptor)

  • obj:要定义属性的对象。
  • prop:要定义或修改的属性的名称。
  • descriptor:要定义或修改的属性描述符。
    返回值:被传递给函数的对象。

三、描述:

  此方法允许精确地添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,可以改变这些属性值,也可以删除这些属性值。默认情况下使用此方法添加的属性值是不可修改的。
对象里目前存在的属性描述符有两种主要形式:

  • 数据描述符:是一个具有值的属性,该值可以是可写的,也可以是不可写的。

    configurable:是否可以重新定义,当且仅当该属性键值为true时,该属性的描述符能够被改变,同时该属性也能从对应的对象上被删除。默认为false。

    enumerable: 是否可以枚举,当且仅当该属性键值为true时,该属性会出现在对象的枚举属性中。默认为false。

    value:该属性对应的值。默认为undefined。

    writable: 是否可以修改属性值,当且仅当该属性的键值为true时,上面的value才能被赋值运算符改变,默认为false。

  • 存取描述符:由getter函数和setter函数所描述的属性还可以具有以下可选键。

    get :属性的getter函数,如果没有getter,则为undefined。动态计算得到当前属性值 (回调函数)。默认为undefined,当访问该属性时,会调用此函数。

    set :监视当前属性值的变化,更新其他相关的属性(回调函数)。当属性值被修改时,会调用此函数。默认为undefined。

注:一个描述符只能是这两者其中之一,不能同时是两者。
这两种描述符都是对象,

描述符可拥有的键值:

configurable enumerable value writable get set
数据描述符 可以 可以 可以 可以 不可以 不可以
存取描述符 可以 可以 不可以 不可以 可以 可以

如果一个描述符不具有value、writable 、get、set中任意一个键,那么它将被认为是一个数据描述符。如果一个描述符同时拥有value或writable和get或set键则会出现异常。

四、代码演示:

创建属性

//    创建属性
    var o = {
    
    };
    Object.defineProperty(o,"a",{
    
    
        value:37,
        writable:true,
        enumerable:true,
        configurable:true
    });
    //对象o拥有了属性a,值为37

    //在对象中添加一个设置了存取描述符属性的示例
    var Bvalue = 38;
    Object.defineProperty(o,"b",{
    
    
        get(){
    
    
            return Bvalue;
        },
        set(newValue){
    
    
            Bvalue = newValue;
        },
        enumerable:true,
        configurable:true
    });

    console.log(o.a);

修改属性writable:当writable属性设置为false时,该属性被称为“不可写的”。

        var o = {
    
    };//创建一个对象
        Object.defineProperty(o,'a',{
    
    
            value:37,
            writable:false,
        })
        console.log(o.a);
        o.a = 25;
        console.log(o.a);

在这里插入图片描述
Enumerable 属性:定义了对象的属性是否可以在 for…in 循环和 Object.keys() 中被枚举。

    var o = {
    
    };
    Object.defineProperty(o,"a",{
    
    value:1,enumerable:true});
    Object.defineProperty(o,"b",{
    
    value:2,enumerable:false});
    Object.defineProperty(o,"c",{
    
    value:3});
    o.d = 4;
    Object.defineProperty(o,Symbol.for('e'),{
    
    
        value:5,
        enumerable:true
    });
    for(var i in o){
    
    
        console.log(i);
    }
    console.log(Object.keys(o));

在这里插入图片描述
configurable 特性:表示对象的属性是否可以被删除,以及除 value 和 writable 特性外的其他特性是否可以被修改。

    var o = {
    
    };
    Object.defineProperty(o,"a",{
    
    
        get(){
    
    return 1},
        configurable:false,
    });
    Object.defineProperty(o,"a",{
    
    
        configurable:true,
    });
    Object.defineProperty(o,"a",{
    
    
        enumerable:true,
    });
    Object.defineProperty(o,"a",{
    
    
        set(){
    
    }
    });
    Object.defineProperty(o,"a",{
    
    
        get(){
    
    return 1},
        configurable:false,
    });
    Object.defineProperty(o,"a",{
    
    
        value:12
    });
    console.log(o.a);
    delete o.a;
    console.log(o.a);

会在第14行报错。
在这里插入图片描述
设置getter()和setter()

    function Archiver() {
    
    
        var temperature = null;
        var archive = [];
        Object.defineProperty(this,'temperature',{
    
    
            get:function(){
    
    
                console.log('get!');
                return temperature;
            },
            set:function(value){
    
    
                temperature = value;
                archive.push({
    
    val:temperature});
            }
        });
        this.getArchive = function(){
    
    return archive};
    }
    var arc = new Archiver();
    arc.temperature; 
    arc.temperature = 11;
    arc.temperature = 13;
    console.log(arc.getArchive()); 

在这里插入图片描述
参考资料:MDN

猜你喜欢

转载自blog.csdn.net/weixin_43690348/article/details/109705374