Object.defineProperty()与数据劫持

         六月份学vue的时候,当时只知道它是双向绑定,数据改变,视图层也会改变;视图改变,数据也会改变。那个时候只求会用,不求甚解。接下来的一段时间内陆陆续续接触到关于双向绑定的知识,大概只知道好像与Object.defineProperty()有关。后面看到一本书JavaScript for php Developer,书上讲到了对象的属性是可以定义权限的,当时记得权限包括:可读可写可枚举等,印象深的记住了这几个,那个时候才知道对象的属性定义背后不简单,但是当时也并没有去深究与数据劫持的关系,只是大脑一直记得有这么个东西。

          后来陆陆续续的又接触到一些零零碎碎的知识和概念,大脑对这些知识有了一些想法,然后就想自己再弄明白这些问题,这个时候自己对这些东西也不抗拒了,想知道什么叫数据劫持,与框架又有什么联系。

           然后最近一直听说前端面试会面ES5实现const,当时我的想法就是使用对象的可读不可写权限,但搁置没有去实现细节。

这两天觉得可以去试试写一写。

           ES5 const 实现:

           ES5 const在全局作用域下定义的变量会挂在window中,并且没有块级作用域的实现(后面会讲)。

           ES5 const通过函数来让一个变量或者属性挂在一个对象上。这里举例用的是window对象。

下面定义的是consts()函数,注意是consts,多了个s加以区分

function consts(variable,value){  //variable:变量名          value:变量值

//     Object.defineProperty()有三个参数,第一个是要挂在哪个对象下面,第二个是属性名或变量名,第三个是一个对象,里面

//     是配置权限

    Object.defineProperty(window,variable,{

                 get:function(){return value},    //在读取属性时调用的函数。默认值为undefined。

                 set:function(anotherVariable){  //在给属性赋值时调用的函数。默认值为undefined。anotherVariable是指给属性赋值

                                                                  //   时的值

                         console.log(`anotherVariable:${anotherVariable};value:${value}`);

                         if(anotherVariable !== value){   //这里使用了闭包,value在这里使用,一直保存在内存中,没有被销毁,然后每

                                                                         //次给属性赋值时会让传过来的值与value比较,用的是!==,如果是相等则表示第

                                                                         //一次赋值,不相等则表示第二次赋值并报错

                                 console.error(`${variable} is already assignmented.`);

                        }else{

                                   return value;//第一次赋值则直接赋值

                 }

},

configurable:false, // 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属

                             //性.默认值为true。

enumerable:false,  表示能否通过for-in循环返回属性。默认值为true.

     })

}

 

consts('a',5);

console.log(a);

a=12;

Object.defineProperty()与数据劫持_第1张图片

 

前面说ES5没有块级作用域,然后现在实现的consts()也是如此,当你在一个函数里使用consts()时,因为consts()定义的变量或者说属性是挂在某个对象上的,所以在这个函数作用域外面也是可以访问这个属性的。但在es6中的const是由块级作用域的,在函数体内用const定义一个变量,外部一般来说是不能访问的(闭包除外)。

Object.defineProperty()与数据劫持_第2张图片

而当用consts()定义一个属性(变量),外部是可以访问的

Object.defineProperty()与数据劫持_第3张图片

Object.defineProperty()与数据劫持_第4张图片

vue双向数据绑定用到了文档碎片documentFragmentObject.definePropertyproxy发布订阅模式这里就只解释了Object.defineProperty(),其它知识点后续深究。

上面对Object.defineProperty()有了大概的了解,可以思考一下它在框架中的运用,我一开始听到数据劫持是不明所以然的,但是明白了Object.defineProperty()的作用后,就大概明白为什么叫做数据劫持了。框架它要做的东西就是在get和set里面,当我们对一个对象的属性进行了改变,它会触发set,然后框架就会将数据的变化表现在视图上。里面框架做了非常多的东西,这里只是浅显地管中窥豹,专研一下很有趣。

       个人见解,里面肯定有不足之处,欢迎讨论.

 

你可能感兴趣的:(Object.defineProperty()与数据劫持)