双向绑定的核心原理
核心是采用数据劫持结合发布者订阅者模式,通过Object.defineProperty()对每个属性的get和set进行拦截。在数据发生变化的时候发布消息给订阅者,触发相应的监听回调。
仅仅使用Object,defineProperty()就能完成一个简单的双向绑定,但是效率比较低。观察者模式让双向绑定更有效率,它是一对多的模式,一指的是修改的一处数据,多是凡是用了这个数据的地方都更新。数据劫持就是利用Object.defineProperty()读操作数据的set,get。
极简的双向绑定
Object.defineProperty()有三个参数,第一个是属性所在的对象。第二个是要操作的属性,第三个是被操作的属性的特性,是一个对象{},一般是两个get:读取属性时触发,set写入属性时触发。
<input type="text" id="inputtext">
<p id="ptext"></p>
let obj={}
Object.defineProperty(obj,'val',{
get:function(){},
set:function(_val){
document.getElementById("inputtext").value=_val
document.getElementById('ptext').innerHTML=_val
}
})
document.addEventListener("keyup",function(e){
obj.val=e.target.value
})
参考:Object— Object.defineProperty()(详解、原理、作用、使用场景、使用方式) - 萬事順意 - 博客园
Object.defineProperty() 是 JavaScript 中用于定义或修改对象的属性的方法,可以控制属性的特性(如可枚举性、可配置性、可写性等)。
Object.defineProperty() 方法的语法如下:
Object.defineProperty(obj, prop, descriptor)
obj:要在其上定义属性的对象。prop:要定义或修改的属性的名称。descriptor:属性的描述符对象,包含属性的特性设置。
descriptor 对象包含以下属性:
configurable:属性是否可配置,默认为false。enumerable:属性是否可枚举,默认为false。value:属性的值,默认为undefined。writable:属性是否可写,默认为false。get:获取属性值的函数。set:设置属性值的函数。
let obj= {
age : '18'
}
Object.defineProperty(obj,'name',{
value : 'red'
})
Object.defineProperty(obj,'age',{
value : '20'
})
console.log(obj) //{age: '20', name: 'red'}
Object.defineProperty() 方法可以用来定义新属性或修改已有属性的特性。如果属性已经存在,Object.defineProperty() 方法将会更新属性的特性;如果属性不存在,Object.defineProperty() 方法将会创建一个新的属性。
需要注意的是,使用 Object.defineProperty() 方法定义的属性默认情况下是不可配置的,这意味着不能使用 delete 关键字删除这些属性。如果需要定义可配置的属性,可以在 descriptor 对象中将 configurable 属性设置为 true。
该示例完整代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>页面学习</title>
</head>
<body>
<input type="text" id="inputtext">
<p id="ptext"></p>
<script type="module">
let obj={}
Object.defineProperty(obj,'val',{
get:function(){},
set:function(_val){
document.getElementById("inputtext").value=_val
document.getElementById('ptext').innerHTML=_val
}
})
document.getElementById("inputtext").addEventListener("keyup",function(e){
obj.val=e.target.value
})
</script>
</body>
</html>
访问页面,如下所示:

在文本框输入内容后,下面也会显示对应的文本

195

被折叠的 条评论
为什么被折叠?



