双向绑定 当obj的值修改时_数据双向绑定之Object.defineProperty

本文介绍了JavaScript中数据双向绑定的实现方式,包括使用`Object.defineProperty`进行数据绑定,探讨了属性设置的各种选项,以及脏检查和观察者机制。特别强调了Vue.js如何通过属性访问器实现数据绑定,并讨论了不同方法的优缺点和兼容性问题。
摘要由CSDN通过智能技术生成

用途:

1. 可以声明不能做任何修改的对象

2. 数据双向绑定

属性设置:

value:值,默认是undefined

writable:是否是只读property,默认是false

enumerable:是否可以被枚举(for

in),默认false

configurable:是否可以被删除,默认false

get:返回property的值得方法,默认是undefined(不能和value、writable同时使用)

set:为property设置值的方法,默认是undefined(不能和value、writable同时使用)

例:

var test =

{

init:function(){

Object.defineProperty(myobj= {},'age', {

value: 18,

writable: true,

enumerable: true,

configurable: true

});

}

}

test.init();

此处声明的myobj对象属于顶层属性,不属于test的属性,即使test的声明在函数作用域内也是如此

即相当于声明为window.myobj

数据双向绑定:

value、configurable、enumerable、writable不能与set同时设置

let obj = {};

let newV;

Object.defineProperty( obj, 'name',

{

set:

function(v){

newV

= v;

//同步更新数据

document.getElementByIdx_x_x_x_x_x_x_x('name')

= v;

},

get:

function(){

return

newV || 0;

}

} );

为对象声明多个属性的方法:

Object.defineProperties (myobj=

{}, {

'name':

{

value:

'canon',

writable:

true,

enumerable:

false,

configurable:

true

},

'age':

{

value:

18,

writable:

true,

enumerable:

true,

configurable:

true

}

});

另外几个与之相关可能会用到的方法

Object.getOwnPropertyDescriptor(obj,property)

获取defineProperty方法设置的property特性

var props =

Object.getOwnPropertyDescriptor(myobj, 'age');

console.log(props)

//{value: 24,

writable: true, enumerable: true, configurable: true}

Object.getOwnPropertyNames(obj)

获取所有的属性名,不包括prototy中的属性,返回一个数组

console.log(Object.getOwnPropertyNames(myobj));

//['name',"age"]

Object.keys(obj)

获取所有的可枚举的属性,返回一个数组

console.log(Object.keys(myobj));

//["age"]

Object.preventExtensions(obj)

锁住对象属性,使其不能够拓展,即不能增加新的属性

但是属性的值仍可更改,也可删除属性

返回该对象

Object.isExtensible(obj)

判断对象是否可以被拓展,返回布尔值

Object.seal(obj)

用于把对象密封,即让对象既不可拓展也不可删除属性(把每个属性的configurable设为false)

但属性值仍然可修改

Object.isSealed(obj)

判断对象是否被密封,返回布尔值

Object.freeze(obj)

冻结对象,在seal的基础上,属性值也不可修改(每个属性的wirtable也被设为false)

Object.isFrozen(obj)

判断对象是否被冻结,返回布尔值

其他:

//脏检查

我们说Angularjs(这里特指AngularJS 1.x.x版本,不代表AngularJS

2.x.x版本)双向数据绑定的技术实现是脏检查,大致的原理就是,

Angularjs内部会维护一个序列,将所有需要监控的属性放在这个序列中,当发生某些特定事件时(注意,

这里并不是定时的而是由某些特殊事件触发的),Angularjs会调用 $digest

方法,这个方法内部做的逻辑就是遍历所有的watcher,

对被监控的属性做对比,对比其在方法调用前后属性值有没有发生变化,如果发生变化,则调用对应的handler。

网上有许多剖析Angularjs双向数据绑定实现原理的文章,比如 这篇 ,再比如 这篇 ,等等。

这种方式的缺点很明显,遍历轮训watcher是非常消耗性能的,特别是当单页的监控数量达到一个数量级的时候。

//观察机制(已废弃,用Object.proxy代替)

博主之前有一篇转载翻译的文章, Object.observe()带来的数据绑定变革 ,说的就是使用ECMAScript7中的

Object.observe 方法对对象

(或者其属性)进行监控观察,一旦其发生变化时,将会执行相应的handler。

这是目前监控属性数据变更最完美的一种方法,语言(浏览器)原生支持,没有什么比这个更好了。唯一的遗憾就是目前支持广度还不行,有待全面推广。

//封装属性访问器

国产mvvm框架vue.js实现数据双向绑定的原理就是属性访问器。

它使用了ECMAScript5.1(ECMA-262)中定义的标准属性 Object.defineProperty

方法。针对国内行情,

部分还不支持 Object.defineProperty

低级浏览器采用VBScript作了完美兼容,不像其他的mvvm框架已经逐渐放弃对低端浏览器的支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值