模拟Vue中v-module数据双向绑定
<style>
#box {
margin-top: 20px;
padding: 10px 20px;
border: 1px solid salmon;
}
</style>
</head>
<body>
<input id="myInput" type="text" />
<p id="box"></p>
<script>
var data = {};
myInput.addEventListener("input", function (e) {
text = e.target.value;
console.log("侦听输入的值", text);
data.value = text;
});
Object.defineProperty(data, "value", {
get() {
return "";
},
set(value) {
console.log("设置的值", value);
box.innerHTML = value;
},
});
</script>
</body>
Object.defineProperty
JS中是支持面向对象编程的,也是有着对象和类这样的概念
我们常见创建对象的方法应该是这样:
var p1 ={
name:"lisi",
}
那我们Object.defineProperty这个方法有什么用呢?
这个方法接收三个参数:
1.属性所在的对象 2.属性的名字 3.一个描述符对象
属性所在的对象 属性的名字
Object.defineProperty(p1, "name",
{ configurable: false, } 一个描述符对象
)
描述符对象是什么?
是 数据属性: 1.configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,默认值为true。
2. enumerable:表示能否通过for in循环访问属性,默认值为true
3. writable:表示能否修改属性的值。默认值为true。
5. value:包含这个属性的数据值。默认值为undefined。
configurable
var p1 = {
name: "list",
}
Object.defineProperty(p1, "name", {
configurable: false,
})
console.log(p1);
delete p1.name;
console.log(p1);
这个方法设置好configurable 这个属性,delete就不能把name属性给删除掉了。
writable
var p1 = {
name: "list",
}
Object.defineProperty(p1, "age", {
writable: false,
value: 15,
})
console.log(p1);
console.log(p1.age);
p1.age = 20;
console.log(p1.age);
然后我们给p1这个对象新加了一个age属性,并且设置成只读的。 这样我们就无法修改这个age属性了。
enumerable
var p1 = {
name: "list",
age: 15
}
Object.defineProperty(p1, "name", {
enumerable: false
})
for (var i in p1) {
console.log(i);
}
给enumerable设置为false,这样对象就不能遍历出age这个属性的值了。
数据劫持get和set方法
第三个参数除了可以是数据属性,也可以是访问器属性。
我们使用Object.defineProperty()函数来实现数据劫持, 主要是通过get和set两个方法来实现数据劫持, 当数据发生改变时触发set方法, 默认值是undefined 当读取某一个属性时,调用的是get方法。 默认值是undefined
let data1 = {
name: '小明',
age: 18
}
Object.defineProperty(data1, 'age', {
set: function (newAge) {
console.log(this.name + '现在' + newAge + '岁')
如果set被调用,则说明想要更改data1.age的值
},
get: function () {
return 19;
当通过data1访问age时,其实获取到的是data1.age
}
})
data1.age = 18;
data1.age = 19;
data1.age = 20;
console.log(data1.age)
在这里看到,我们获取data1.age 的时候只能是得到19,因为本质上data1={ name: '小明', age: [Getter/Setter] } , 也就是说我在使用data1.age 方法时候是在使用get 方法,而get方法返回值一直是19, 所以我一直获取不了最新的值。
转换思想
通过data中添加一个属性_age来变相的达到数据同步。
let data1 = {
name: '小明',
_age: 18
}
Object.defineProperty(data1, 'age', {
set: function (newAge) {
this._age = newAge
console.log(this.name + '现在' + newAge + '岁')
},
get: function () {
return this._age;
}
})
data1.age = 18;
data1.age = 19;
data1.age = 20;
console.log(data1.age)
获取data1.age 的数据是最新设置的20,
深层讲解链接
|