<JS>Object.defineProperty(

作者: 泡沫的快乐 | 来源:发表于2017-06-14 01:24 被阅读30次

    只是按照我所理解的进行说明。
    该方法运行更加精确控制对象的属性。

    >>语法
    Object.defineProperty(obj, attr, descriptor)
    1: obj:要在其上定义属性的对象。
    2: attr:要定义或修改的属性的名称。只能定义一个。
    3: descriptor:将被定义或修改的属性描述符(具体看下面👇)。
    

    要同时定义多个属性可使用 Object.defineProperties()

    >>属性描述符
    属性描述符分为: 数据描述符 和 存取描述符.
    
    >>数据描述符,存取描述符 共有可选键值:
    configurable: 当该属性为 true 时,该属性描述符才能够被改变,该属性也能够被删除。默认为 false。
    若手动设置为false,那就再也无法修改任何描述符(除writable描述符要设置为false时)!
    enumerable: 当该属性 为 true 时,该属性才能够出现在对象的枚举属性中(是否能在for...in, Object.keys()中被枚举)。默认为 false。
    
    >>数据描述符 可选键值:
    value: 该属性的值。 (可以是任何JS有效值)。 默认为undefined。
    writable: 概述为true时,赋值运算符赋值才会成功。默认为false。
    
    >>存取描述符 可选键值:
    get: 在获取该属性的值时 调用的函数,该方法返回值作为属性的值。 默认为undefined。
    set: 在修改该属性的值时 调用的函数(默认传入修改的值)。  默认为undefined。
    
    注意

    1: 在用Object.defineProperty()设置时,只能同时对一类型描述符进行设置。否则会报错。 测试:

    let o = {};
    Object.defineProperty(o, 'test', {
        value:1, //数据描述符
        get(){ // 存取描述符.
            return '测试'
        }
    });//会报错,因为不能同时对 两种类型的描述符进行操作.
    

    2: 正常创建属性。描述符都会被赋值,而不是默认值。
    下面用这个方法——Object.getOwnPropertyDescriptor()
    查询描述符信息。测试:

    let o = {
        test:1
    }// 可能你会以为,描述符会被赋值为上面所写的默认值。
    let info = Object.getOwnPropertyDescriptor(o,'test');
    console.log(info) 
    /* 显示信息如下
     * configurable:true
     * enumerable:true
     * value:1
     * writable:true 
     */
    在正常创建属性时,描述符都会被赋值。 大概情况为:
    configuraable, enumerable, writable, 赋值为true.
    value为所赋的值.
    

    3: 描述符会被赋值为默认值的情况

    >>数据描述符 设置为默认值
    let o = {}  // 在使用↓方法时,没有写的描述符,会被赋值为默认值。
    Object.defineProperty(o, 'test', {}); //默认设置数据描述符
    let info = Object.getOwnPropertyDescriptor(o,'test'); //获取描述符信息
    console.log(info) 
    /* 显示信息如下
     * configurable:false
     * enumerable:false
     * value:undefined
     * writable:false
     */
    set, get方法应该还是正常返回值,修改值。
    
    >>存取描述符 设置为默认值
    let o = {};
    Object.defineProperty(o, 'test', {
        set(){} // 因为默认会设置数据描述符的默认值,所以设置下get, 让set为默认值。
    })
    let info = Object.getOwnPropertyDescriptor(o,'test');
    console.log(info);
    /* 显示信息如下
     * configurable:false
     * enumerable:false
     * set:function set() //我手动设置的
     * get:undefined //默认值
     */
    
    重点:如果属性是通过此方法设置的,那么没有主动设置的描述符键值,它会被设置为,默认值(导致属性无法访问,无法修改)。
    所以要记得在使用此方法定义属性时,给必要描述符键值进行设置,除非默认值符合你预期。
    
    >>实践
    简单写一个数据双向绑定.(不需要记忆,只是展示其功能)
    function getAndSet(obj, attr, getFn, setFn){
        let nowVal = obj[attr];
        Object.defineProperty(obj, attr, {
            configurable:true,
            enumerable:true,
            get(){
                getFn(nowVal) // 在获取时调用的方法
                //可以写DOM操作,使其在数据改变的时候,DOM相应改变
                return nowVal
            },
            set(newVal){
                setFn(newVal, nowVal) // 在修改时调用的方法
                //可以写DOM操作,使其在数据改变的时候,DOM相应改变
    
                nowVal = newVal;
                return newVal
            },
        })
    }
    let o = {
        test:1
    };
    getAndSet(o, 'test', function(nowVal){
        console.log(`get方法! 值:${nowVal}`)
    },function(newVal, nowVal){
        console.log(`set方法! 新值:${newVal},原值:${nowVal}`)
    })
    o.test // get方法! 值:1
    o.test = 4 // set方法! 新值:4,原值:1
    
    当属性值是对象时,函数就没效果了。毕竟只是简单的实现,你可以让其的所有属性再次去调用此方法。
    更加复杂,强大的实现,可以去学Vue框架。
    

    以上是我所知的的东西,有任何错误,请在评论指出!
    O(∩_∩)O谢谢你的观看~

    相关文章

      网友评论

        本文标题:<JS>Object.defineProperty(

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