• Object.definePropety


    defineProperty

    Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象,也就是说,该方法允许精确地添加或修改对象的属性。

    语法

    Object.defineProperty(obj, prop, descriptor)
    obj: 要定义属性的对象。
    prop: 要定义或修改的属性的名称或Symbol
    descriptor: 要定义或修改的属性描述符。

    属性描述符

    对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由getter函数和setter函数所描述的属性。一个描述符只能是数据描述符和存取描述符这两者其中之一,不能同时是两者。

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

    如果一个描述符不具有valuewritablegetset中的任意一个键,那么它将被认为是一个数据描述符。如果一个描述符同时拥有valuewritablegetset键,则会产生一个异常。
    此外,这些选项不一定是自身属性,也要考虑继承来的属性。为了确认保留这些默认值,在设置之前,可能要冻结Object.prototype,明确指定所有的选项,或者通过Object.create(null)__proto__属性指向null

    configurable

    当且仅当该属性的configurable键值为true时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除,默认为false,默认值是指在使用Object.defineProperty()定义属性时的默认值。

    "use strict";
    // 非严格模式下操作静默失败,即不报错也没有任何效果
    // 严格模式下操作失败抛出异常
    
    var obj = {};
    Object.defineProperty(obj, "key", {
        configurable: true,
        value: 1
    });
    console.log(obj.key); // 1
    Object.defineProperty(obj, "key", {
        enumerable: true // configurable为true时可以改变描述符
    });
    delete obj.key; // configurable为true时可以删除属性
    console.log(obj.key); // undefined
    
    "use strict";
    var obj = {};
    Object.defineProperty(obj, "key", {
        configurable: false,
        value: 1
    });
    console.log(obj.key); // 1
    Object.defineProperty(obj, "key", {
        enumerable: true // configurable为false时不可以改变描述符 // Uncaught TypeError: Cannot redefine property: key
    });
    delete obj.key; // configurable为false时不可以删除属性 // Uncaught TypeError: Cannot delete property 'key' of #<Object>
    console.log(obj.key); // undefined
    

    enumerable

    当且仅当该属性的enumerable键值为true时,该属性才会出现在对象的枚举属性中,默认为 false

    "use strict";
    var obj = { a: 1 };
    Object.defineProperty(obj, "key", {
        enumerable: true,
        value: 1
    });
    for(let item in obj) console.log(item, obj[item]); 
    /* 
      a 1
      key 1
    */
    
    "use strict";
    var obj = { a: 1 };
    Object.defineProperty(obj, "key", {
        enumerable: false,
        value: 1
    });
    for(let item in obj) console.log(item, obj[item]); 
    /* 
      a 1
    */
    

    value

    该属性对应的值,可以是任何有效的JavaScript值,默认为undefined

    "use strict";
    var obj = {};
    Object.defineProperty(obj, "key", {
        value: 1
    });
    console.log(obj.key); // 1
    
    "use strict";
    var obj = {};
    Object.defineProperty(obj, "key", {});
    console.log(obj.key); // undefined
    

    writable

    当且仅当该属性的writable键值为true时,属性的值,才能被赋值运算符改变,默认为 false

    "use strict";
    var obj = {};
    Object.defineProperty(obj, "key", {
        value: 1,
        writable: true
    });
    console.log(obj.key); // 1
    obj.key = 11;
    console.log(obj.key); // 11
    
    "use strict";
    var obj = {};
    Object.defineProperty(obj, "key", {
        value: 1,
        writable: false,
        configurable: true
    });
    console.log(obj.key); // 1
    obj.key = 11; // Uncaught TypeError: Cannot assign to read only property 'key' of object '#<Object>'
    Object.defineProperty(obj, "key", {
        value: 11 // 可以通过redefine来改变值,注意configurable需要为true
    });
    console.log(obj.key); // 11
    

    get

    属性的getter函数,如果没有getter,则为undefined。当访问该属性时,会调用此函数,执行时不传入任何参数,但是会传入this对象,由于继承关系,这里的this并不一定是定义该属性的对象。该函数的返回值会被用作属性的值,默认为undefined

    "use strict";
    var obj = { __x: 1 };
    Object.defineProperty(obj, "x", {
        get: function(){ return this.__x; }
    });
    console.log(obj.x); // 1
    
    "use strict";
    var obj = { __x: 1 };
    Object.defineProperty(obj, "x", {
        get: function(){ return this.__x; }
    });
    console.log(obj.x); // 1
    obj.x = 11; // 没有set方法 不能直接赋值 // Uncaught TypeError: Cannot set property x of #<Object> which has only a getter
    

    set

    属性的setter函数,如果没有setter,则为undefined。当属性值被修改时,会调用此函数,该方法接收一个参数,且传入赋值时的this对象,从而进行赋值操作,默认为undefined

    "use strict";
    var obj = { __x: 1 };
    Object.defineProperty(obj, "x", {
        set: function(x){ this.__x = x; },
        get: function(){ return this.__x; }
    });
    obj.x = 11;
    console.log(obj.x); // 11
    
    "use strict";
    var obj = { __x: 1 };
    Object.defineProperty(obj, "x", {
        set: function(x){ 
            console.log("在赋值前可以进行其他操作");
            this.__x = x; 
        }
    });
    obj.x = 11;
    

    相关

    Js严格模式 https://github.com/WindrunnerMax/EveryDay/blob/master/JavaScript/Js%E4%B8%A5%E6%A0%BC%E6%A8%A1%E5%BC%8F.md
    Js遍历对象 https://github.com/WindrunnerMax/EveryDay/blob/master/JavaScript/Js%E9%81%8D%E5%8E%86%E5%AF%B9%E8%B1%A1%E6%80%BB%E7%BB%93.md
    

    每日一题

    https://github.com/WindrunnerMax/EveryDay
    

    参考

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
    
  • 相关阅读:
    java8新特性之Lambda表达式入门
    小结
    Kafka入门
    关于java多线程初试
    关于Netty入门
    IOS UITableView代码添加数据源和指定委托
    C#读书笔记1
    vs2008 C# Windows Mobile 智能设备开发 初步1
    Microsoft ActiveSync简介(来自网络)
    winForm单击用户区可移动窗体,代码控制窗体最大适中
  • 原文地址:https://www.cnblogs.com/WindrunnerMax/p/12875272.html
Copyright © 2020-2023  润新知