欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Object.defineProperty 实现双向数据绑定的那些事

程序员文章站 2022-07-12 21:58:59
...

defineProperty是干什么的

意如其名,Object.defineProperty 是用来给一个对象定义属性的方法,属性按功能分为2类,数据属性(相当于通过.操作符定义属性),访问器属性(实现双向绑定)。

defineProperty定义数据属性与对象实例直接通过“.”运算符定义属性的区别

var testObject = {};
Object.defineProperty(testObject, 'hello', {
    value: 12,
    // configurable: true,
    // enumerable: true,
    // writable: true,
});
console.log(testObject.hello);   // 12
delete testObject.hello;
console.log(testObject.hello);   // 12
testObject.hello = 22;
console.log(testObject.hello);  // 12
for (let props in testObject) {
    console.log(props);  // 没有任何输出
}

以上代码可以看出,通过defineProperty定义的属性,默认是不可通过delete删除属性,for in 循环出来, 不可修改的。而直接通过.定义属性是可以删除修改,遍历的。defineProperty定义属性时,可配置configurable(是否可删除), enumerable(是否可遍历),writable(是否修改)三个属性,并且默认为false。

属性 可删除 可修改 可遍历
configurable true
enumerable true
writable true

defineProperty定义访问器属性(实现双向绑定的基础)

访问器属性有一下4个特性。
configurable(可删除)、enumerable(可遍历)、get、set。

var testObject = {
   _year: 2019,
   version: 1,
};
Object.defineProperty(testObject, 'year', {
   /configurable: true,
   /enumerable: true,
   get: function () {
       return this._year;
   },
   set: function (newYear) {
       this._year = newYear;
       this.version = newYear - 2019;
   }
});
testObject.year = 2021;
console.log(testObject.year); // 2021 
var des = Object.getOwnPropertyDescriptor(testObject, 'year');
console.log(des); // {get: ƒ, set: ƒ, enumerable: false, configurable: false}

由此可见,在定义访问器属性是,set和get方法用来处理数据修改和获取是的行为。enumerable和configurable默认都为false。

Object.defineProperty如何实现双向绑定

dom元素与属性进行绑定,相当于对dom元素添加watch,检测数据变化,变化时,调用set方法,修改对象(modal),当对象值发生改变是,调用get方法,重新给dom赋值。