defineProperty
双向数据绑定
defineProperty
首先需要声明的是这个是ES5的特性,兼容大多数浏览器,除了ie8仍旧是被嫌弃的存在
Object.defineProperty ,顾名思义,为对象定义属性。在js中我们可以通过下面这几种方法定义属性
obj = {}
1:
obj.name = 'hello'
===================================
2:
obj['name'] = 'hello'
===================================
3:
obj.defineProperty(obj, 'name', {
value: 'hello'
})
Object的defineProperty和defineProperties这两个方法在主要功能就是用来定义或修改对象的内部属性,与之相对应的getOwnPropertyDescriptor和getOwnPropertyDescriptors就是获取对象的内部属性的描述。
ECMAScript对象中目前存在的属性描述符主要有两种,数据描述符(数据属性)和存取描述符(访问器属性),数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对 getter-setter 函数功能来描述的属性。
数据描述符
[configurable]
默认值false,表示能否通过delete删除此属性, 能否修改属性的特性,或能否修改把属性修改为访问器属性。
ps:如果直接使用字面量定义对象,默认值为true
[enumberable]
默认值false,表示该属性是否可枚举,即是否通过for-in循环或Object.keys()返回属性。
ps:如果直接使用字面量定义对象,默认值为true
[writable]
默认值false,能否修改属性的值。
ps:如果直接使用字面量定义对象,默认值为true
[value]
默认值undefined,表示该属性的值
访问器(存取描述符)属性
[configurable]
同上
[enumberable]
同上
[get]
默认值undefined,一个给属性提供 getter 的方法(访问对象属性时调用的函数,返回值就是当前属性的值),如果没有 getter 则为 undefined。该方法返回值被用作属性值
[set]
默认值undefined,一个给属性提供 setter 的方法(给对象属性设置值时调用的函数),如果没有 setter 则为 undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。
双向数据绑定2
创建/修改/获取属性的方法
Object.defineProperty()
Object.defineProperties()
Object.defineProperty(obj, prop, descriptor)
/**
* obj: 需要被操作的目标对象
* prop: 目标对象需要定义或修改的属性的名称
* descriptor: 将被定义或修改的属性的描述符
*/
var obj = {}
Object.defineProperty(obj, 'a', {
configurable: false,
writable: true,
enumerable: true,
value: '123'
})
console.log(obj.name) //123
Object.defineProperties(obj, props)
/**
* obj: 将要被添加属性或修改属性的对象
* props: 该对象的一个或多个键值对定义了将要为对象添加或修改的属性的具体配置
*/
var obj = new Object();
Object.defineProperties(obj, {
name: {
value: '张三',
configurable: false,
writable: true,
enumerable: true
},
age: {
value: 18,
configurable: true
}
})
console.log(obj.name, obj.age) // 张三, 18
同理可推导
Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptors()
[set] && [get]
需要理解的是 设置是设置 取值是取值
let obj = {}
Object.defineProperty(obj, 'a', {
configurable: true,
get: function() {
return 0
},
set: function(newVal) {
console.log('set newVal is:', newVal)
}
})
obj.a = 'hello' // => set newVal is:hello
console.log(obj.a) // => 0
// 上面是设置的过程执行set
// 下面是取值的过程执行get
利用set的方法和get的过程我们可以实行双向数据绑定
var act = $('#account')
var pwd = $('#pwd')
var dd = $('#dd')
var obj = {}
Object.defineProperties(obj, {
val1: {
configurable: true,
get: function(){
act.val(0)
pwd.val(0)
dd.html(0)
return 0
},
set: function(newVal){
pwd.val(newVal)
var b = Number(newVal) ? Number(newVal) : 0
dd.html(b)
}
},
val2: {
configurable: true,
get: function(){
act.val(0)
pwd.val(0)
dd.html(0)
return 0
},
set: function(newVal){
act.val(newVal)
dd.html(Number(newVal)+1)
}
}
})
act.val(obj.val1)
act.on('input', function() {
var a = act.val()
obj.val1 = a
})
pwd.on('input', function() {
var a = pwd.val()
obj.val2 = a
})
用途:set 可以优化属性设置
get可以优化输出:例如对象某些功能废弃,则可以使用get返回错误信息