• Vue的数据双向绑定原理——Object-defineProperty


    一、定义

    ①方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。

    ②vue.js的双向数据绑定就是通过Object.defineProperty方法实现的,俗称属性拦截器。

    二、语法

    ①语法

    /*
     * @param: obj:需要定义属性的对象; 
     *         prop:需要定义或修改的属性;
     *         descriptor:将被定义或修改属性的描述符
    */
    Object.defineProperty(obj,prop,descriptor)

    ②对象里目前存在的属性描述符主要有两种形式: 数据描述符和存取描述符

    • 数据描述符: 拥有可写或不可写值的属性
    可选键值: 
    configurable: 当且仅当configurable为true时,改属性描述符才能够被改变,也能被删除 
    enumerable: 当其值为true时,该属性才能够出现在对象的枚举属性中,默认为false 
    writable: 当且仅当该属性的值为true时,该属性才能被赋值运算符改变, 默认为false。 
    value: 该属性对应的值,可以是任意有效的javascript的值(数值,对象,函数等),默认为undefined
    • 存取描述符: 由一对getter-setter函数功能来描述的属性
    可选键值: 
    configurable: 当且仅当configurable为true时,改属性描述符才能够被改变,也能被删除 
    enumerable: 当其值为true时,该属性才能够出现在对象的枚举属性中,默认为false 
    get: 给属性提供getter的方法,如果没有 getter 则为undefined。当我们读取某个属性的时候,其实是在对象内部调用了该 方法,此方法必须要有return语句。该方法返回值被用作属性值。默认为 undefined 
    set:设置属性值的方法, 如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为 undefined。也就是说,当我们设置某个属性的时候,实际上是在对象的内部调用了该方法

    ③示范:

            let user={
                foo:'bar'
            };
            user.age=18;
            user['name']='eric';
            Object.defineProperty(user,'gender',{
                // value:'男'
                // value 和get两者只能取其一,因为是矛盾的
                // get属性用于属性访问,当访问gender的时候,会自动调用get方法
                get:function(){
                    console.log('取值操作了')
                    return 123
                },
                // set 属性设置器,当设置user.gender=xxx,则会自动调用set方法,xxx作为set的参数
                set:function(value){
                    console.log('赋值操作'+value)
                }
            });  
            // user.gender      取值操作了 123
            // user.gender=666  赋值操作666

    三、例子

    ①设置user.age 如果要对age赋值,则限制age的取值范围:0-120之间

            var age=0;
            var user={};
            Object.defineProperty(user,'age',{
                //value:18,
                get:function(){
                    return age;
                },
                set:function(val){
                    if(val<0||val>120){
                        throw new Error('age invalid')
                    }
                    // 赋值(不能直接赋值,需要有一个中间变量)
                    age=val;
                },
            });
            // user.age    0
            // user.age=1   1
            // user.age=-1  age invalid

    当data.message的值改变的时候更新#test的视图

        <div id="test">这是一个测试</div>
        <script> 
            var view = document.getElementById("test");
            var data = {};
            var i = 0;
            Object.defineProperty(data, "message", {
                set: function (newValue) {
                    //当data.message的值改变的时候更新#test的视图 
                    view.textContent = newValue;
                },
            });
            setInterval(function () {
                i++;
                data["message"] = "data.message的值更新了,我要更新视图" + i;
            }, 1000); 
        </script>

  • 相关阅读:
    GCJ 2015-Qualification-A Standing Ovation 难度:0
    CF 103E Buying Sets 最大权闭合子图,匹配 难度:4
    HDU 1560 DNA sequence A* 难度:1
    蓝桥杯练习系统 矩阵翻硬币 大数,牛顿迭代法 难度:2
    Operating System Concepts with java 项目: Shell Unix 和历史特点
    HDU 2181 哈密顿绕行世界问题 dfs 难度:1
    HDU 3533 Escape bfs 难度:1
    HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3
    POJ 1011 Sticks dfs,剪枝 难度:2
    UVALive 5905 Pool Construction 最小割,s-t割性质 难度:3
  • 原文地址:https://www.cnblogs.com/EricZLin/p/9372936.html
Copyright © 2020-2023  润新知