• 揭秘Object.defineProperty()的本质


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

    value

    该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。

    默认为 undefined。

    writable

    当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符 (en-US)改变。

    默认为 false。

    get

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

    默认为 undefined。

    set

    属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。

    默认为 undefined。

    例1:

    const object1 = {};
    
    Object.defineProperty(object1, 'property1', {
      value: 42,
      writable: false
    });
    
    object1.property1 = 77;
    // throws an error in strict mode
    
    console.log(object1.property1);
    // expected output: 42

    分析:首先,如果object1这个对象不展开的话,控制台打印出来的结果会以“{}”的形式存在,什么属性都没有,而展开它才能看得到。而且,property1这个属性也不能直接看到value值,需要点击“(...)”才能看得到。最后,当直接修改object1这个对象的property1的值的时候,控制台还会报错,而它原本的value值也并不会发声变化。这是因为property1是object1这个对象的扩展属性。

    例2:

    const data = {
        name: Tom,
        age: 18
    };
    
    const object1 = {};
    
    for(let item in data){
        Object.defineProperty(object1, 'item', {
            get(){
                console.log('get()');
                return data[item];
            },
            set(newValue){
                console.log('set()', newValue);
                data[item] = newValue;
            }
        };
    }
    
    object1.name= Jerry;
    
    console.log(object1.property1);
    // expected output: Jerry

    分析:get()是用来获取属性值,当获取该属性值的时候调用get方法,但是通过Object.defineProperty的get方法添加的扩展属性不能直接修改。set()是监视扩展属性,只要值已修改就调用set方法。那么这个例子的整体思路就是,当object1的name属性修改时,先调用set方法,把最新的newValue值赋值给data,然后把data中对应的item属性修改,而data的item属性一修改,object1的item也会随之改变。这就是vue数据劫持代理的底层原理核心思想。

  • 相关阅读:
    zabbix笔记之计算型监控项详解
    zabbix笔记之磁盘IO介绍
    zabbix笔记之Graphtree配置
    zabbix笔记之告警时远程执行命令
    zabbix笔记之异常优化
    zabbix笔记之IPMI配置
    基本的sql 语句
    socket 套接字
    调用父类的三种方法
    实例属性和类属性
  • 原文地址:https://www.cnblogs.com/gyx19930120/p/15567479.html
Copyright © 2020-2023  润新知