defineProperty vue双向绑定
ECMA-262第5版在定义只有内部才用的特性(attribute)时,
描述了属性(property)的各种特征。
ECMA-262定义这些特性是为了实现javascript引擎用的,
对象的属性分为两种类型:数据属性和访问器属性
1.数据属性:数据属性是一个具有值的属性,该值可以是可写的,也可以是不可写的
1.访问器属性:访问器属性是由 getter 函数和 setter 函数所描述的属性。
一个描述符只能是这两者其中之一;不能同时是两者。
,给已有的数据属性加get或set转换为访问器属性时,其属性的value、writable就会被废弃。
configurable- 当且仅当该属性的
configurable键值为true时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。 enumerable- 当且仅当该属性的
enumerable键值为true时,该属性才会出现在对象的枚举属性中。
数据描述符还具有以下可选键值:
value
- 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。
默认为 undefined writable- 当且仅当该属性的
writable键值为true时,属性的值,也就是上面的value,才能被赋值运算符改变。
存取描述符还具有以下可选键值:
get- 属性的 getter 函数,如果没有 getter,则为
undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。
默认为 undefined。 set- 属性的 setter 函数,如果没有 setter,则为
undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的this对象。
默认为 undefined。 -
var person = new Object();person.name = 'Nicy';
var person = {name: 'Nicy'}
通过以上两种方式添加的对象属性,其布尔值特性默认值是true,通过Object.defineProperty来修改属性特性时,只设置需要修改的特性即可;
而通过Object.defineProperty创建的属性,其布尔值特性默认值是false。Object.getOwnPropertyDescriptor 读取属性的特性
通过Object.defineProperties()可以一次性为对象定义多个属性
var person = {}
person.age='10';//添加的属性默认数据类型都是true
for(let key in person){
console.log(key,person[key]) // "age" "10"
}
person.age='20';//所以writable是true所以修改为name2,enumerable也是true在for in 可以找到Object.defineProperty(person, "name", {value: 'Nicy'})
//defineProperty添加的属性默认数据类型都是false,所以writable是false,enumerable也是false无法进行枚举person.name = 'Lee';//无法修改在非严格模式不报错,但是不执行。严格模式报错
console.log(person.name) //"Nicy" // 打印结果仍然是defineProperty的赋值 'Nicy'Object.defineProperty(person, "name2", {
writable: true
})
person.name2 = 'Lee';
console.log(person.name2) // 'Lee'
for(let key in person){
console.log(key,person[key]) //"age" "20"
}
console.log(Object.getOwnPropertyDescriptor(person,'age'))
//{ value: "20", writable: true, enumerable: true, configurable: true }
console.log(Object.getOwnPropertyDescriptor(person,'name'))
//{ value: "20", writable: true, enumerable: true, configurable: true }
console.log(Object.getOwnPropertyDescriptor(person,'name2'))
//{ value: "Lee", writable: true, enumerable: false, configurable: false }Vue内部实现时用到了ES5的Object.defineProperty()这个API,也正是这个原因,
所以Vue不支持IE8及以下浏览器(IE8及以下浏览器是不支持ECMASCRIPT 5的Object.defineProperty())。
vue双向绑定原理
当你把一个普通的 JavaScript 对象传给 Vue 实例的 data 选项,Vue 将遍历此对象所有的属性,并使用
Object.defineProperty(ES5 中一个无法 shim 的特性)把这些属性全部转为getter/setter。这些
getter/setter对用户来说是不可见的,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。
详细原理实现
https://blog.csdn.net/MeiLuan_yahoho/article/details/87912553

浙公网安备 33010602011771号