defineProperty
Object提供的方法,用于给对象添加自定义属性具体用法如下:
const obj = { _value: 1 }; Object.defineProperty(obj, 'value', { get: function() { console.log('get方法执行'); return this._value; }, set: function(a) { console.log('set方法执行'); this._value = a; } }) obj.value = 3; console.log(obj.value); console.log(obj._value);
在node中执行结果如下:
下面来分析一下代码
首先定一个对象,并对对象添加一个自定义属性value,同时添加了getter,setter两个函数用来分别控制value属性的修改和获取,
当执行obj.value = 3;
时,会自动调属性的setter方法,将value的修改同步到_value属性上,当执行obj.value
语句获取属性值时,会自动调用getter方法获取方法的返回值;
总结 (参考MDN)
该方法接收三个参数
obj:要添加属性的对象
prop: 要定义的属性
descriptor:要定义或者修改的属性描述符
其中描述符包含以下几种
1.configurable:布尔值,控制属性是否能改变(除了value,writable)及删除
2.enumerable: 布尔值,控制属性是否可枚举,即通过for in循环或者Object.keys访问
3.value:属性值,可以时任何有效JavaScript值
4.writable 布尔值,属性可否通过赋值修改
5.get:属性getter函数,执行时传入this,this值取决于调用者
6.set:属性setter函数,赋值时执行,并传入this
双向绑定
由此可以设计一下数据双向绑定的简单实现:
在数据对象内定义属性,通过对dom绑定事件监听dom内值的变化,并赋值给数据对象,数据对象的改动会调用自身的setter方法,在方法内在动态修改dom内容。
代码如下:
<!-- 简单数据双向绑定实现 --> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <body> <div id="root"> <button id='btn'>请求数据</button> </div> </body> <script> const root = document.getElementById('root'); const btn = document.getElementById('btn'); const input = document.createElement('input'); const model = document.createElement('p'); const dataModel = { _value:0, } Object.defineProperty(dataModel, 'value', { configurable: true, set:function(value){ this._value = value; input.value = value; model.innerHTML = `<span>数据模型:</sapn> ${value}`; }, get:function(){ return this._value; } }) btn.addEventListener('click', () => { const range = Math.floor(Math.random(0, 1) * 100); dataModel.value = range; }) input.addEventListener('input',(ev) => { dataModel.value = ev.target.value; }) const initPage = () => { dataModel.value = 100; } initPage(); root.append(input); root.append(model); </script> </html>
描述有点乱,看实现代码更清晰一点,有问题欢迎指正