想要了解数据双向绑定原理的实现呢
首先我们需要知道Object.defineProperty ()这个函数是干嘛的,当然,这个方法也是Vue数据双向绑定原理的常见面试题
所以也是有必要好好掌握的哦!!!
好啦,话不多说,开怼
那我们Object.defineProperty()这个方法有什么用呢?
这个方法接收三个参数:
1.属性所在的对象
2.属性的名字
3.一个描述符对象
这个描述符对象是个什么东西呢?有两种表现形式
他可以是 数据属性:
1.configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,默认值为true。
2.enumerable:表示能否通过for in循环访问属性,默认值为true
3.writable:表示能否修改属性的值。默认值为true。
4.value:包含这个属性的数据值。默认值为undefined。
也可以是访问器属性:
1.get:在读取属性时调用的函数,默认值是undefined
2.set:在写入属性的时候调用的函数,默认值是undefined
下面我们 就以第一种表现形式来玩一哈
1. configurable : false
var p1 ={
name:"lisi",
}
Object.defineProperty(p1,"name",{
configurable : false,
})
console.log(p1); //{ name: 'lisi' }
delete p1.name;
console.log(p1); //{ name: 'lisi' }
通过这个方法设置好configurable 这个属性,delete就不能把name属性给删除掉了。
2.writable : false
var p1 ={
name:"lisi",
}
Object.defineProperty(p1,"age",{
writable : false,
value : 15,
})
console.log(p1.age); //15
p1.age = 20;
console.log(p1.age); //15
然后我们给p1这个对象新加了一个age属性,并且设置成只读的。
这样我们就无法修改这个age属性了。
3.enumerable:false
var p1 ={
name:"lisi",
}
Object.defineProperty(p1,"age",{
enumerable:false,
value : 15,
})
for (var i in p1) {
console.log(p1[i])
} // // lisi
在通过这个方法给enumerable设置为false,这样对象就不能通过迭代器遍历出age这个属性的值了。
通过这几个例子,我们基本那就了解Object.defineProperty这个方法的使用以及数据属性是做什么的了。
那该方法的第三个参数除了可以是数据属性,也可以是访问器属性。
1.get:在读取属性时调用的函数,默认值是undefined
2.set:在写入属性的时候调用的函数,默认值是undefined
现在我们来用这两个方法来实践一下:
var book = {
_year : 2004,
edition : 1
}
Object.defineProperty(book,"year",{
get: function(){
return this._year
},
set: function(newYear){
if(newYear > 2004){
this._year = newYear;
this.edition += newYear - 2004
}
}
})
book.year = 2005;
console.log(book.edition); // 2
console.log(book._year); //2005
由于get方法返回_year的值,set方法通过计算来确定正确的版本。
因此把year的值设置为2005会导致edition的值变为2.
OK,关于Object.defineProperty方法的第三个参数的两种属性也就说完了。
最后我们再说一下如何进行定义多个属性
var student = {};
Object.defineProperties(student,{
name:{
writable:false,
value:"lisi"
},
age : {
writable:true,
value : 16,
},
sex:{
get(){
return '男';
},
set(v){
p1.sex = v
}
}
})
p1.sex = "男";
console.log(student.name + ":" + student.age);
console.log(p1.sex); // 男
student.sex = "女";
console.log(student.sex); //男
console.log(p1.sex); // 女
最后我在附上一个模拟Vue中v-module数据双向绑定原理的代码:
<input type="text" id="textInput">
输入: <span id="textSpan"></span>
<script>
var Obj = {}
textInput = document.querySelector('#textInput') // 输入
textSpan = document.querySelector('#textSpan') // 输出
Object.defineProperty(Obj, 'name', {
get: function () {
console.log('get');
return v
},
set: function (val) {
console.log('set');
v = val
}
})
// Obj.a = 123
// Obj.a
textInput.onkeyup = function() {
Obj.name = textInput.value
textSpan.innerHTML = Obj.name
}
</script>
参考文章:Object.defineProperty方法(详解)_爱前端的小菜的博客-CSDN博客_object.defineproperty