用过vue的人都知道,vue有一个特别好用的数据绑定,只要绑定了,你只要改变了这个数据,页面也会跟着渲染。其实原生的JS也是可以做到的,vue其实就是用了原生的原理。
Object.defineProperty,语法是Object.defineProperty(obj, prop, descriptor)
obj:就是一个对象;
prop:就是你要监听的obj里面的某个数据;
descriptor:目标属性所拥有的特性;
这三个都是必须的,前两个都好理解,第三个,说简单点就是这个方法自带的几个特性:Value、writable、enumerable、configurable和getter、setter,其中,getter、setter和Value、writable是不能一起用的。
configurable:true或false,属性是否能删除和再次设置,默认false;
enumerable:true或false,属性是否能枚举,默认false;
value:任意类型的值,默认undefined;
writable:true或false,属性是否能被重写,默认false;
value:
var obj = {}-------每个方法都要有,下面例子就不一一声明
//不设置value属性
Object.defineProperty(obj,"val",{
});
console.log( obj.val ); //输出undefined
//设置value属性
Object.defineProperty(obj,"val",{
value:"hello"
});
console.log( obj.val ); //输出hello
Writable:
//writable设置为false,不能重写。
Object.defineProperty(obj,"val",{
value:"hello",
writable:false
});
obj.newKey = "change";
console.log(obj.val); //输出hello
//writable设置为true,可以重写
Object.defineProperty(obj,"val",{
value:"hello",
writable:true
});
obj.val = "change";
console.log(obj.val); //输出change
enumerable:
//enumerable设置为false,不能被枚举。
Object.defineProperty(obj,"val",{
value:"hello",
enumerable:false
});
for( var val in obj ){
console.log( val ); //输出空
}
//enumerable设置为true,可以被枚举。
Object.defineProperty(obj,"val",{
value:"hello",
enumerable:true
});
//枚举对象的属性
for( var val in obj ){
console.log( val ); //输出val
}
configurable:
//configurable设置为false,不能被删除。
Object.defineProperty(obj,"val",{
value:"hello",
configurable:false
});
//删除属性
delete obj.val;
console.log( obj.val ); //输出hello
//configurable设置为true,可以被删除。
Object.defineProperty(obj,"val ",{
value:"hello",
configurable:true
});
//删除属性
delete obj.val ;
console.log(obj.val); //输出undefined
//configurable设置为false,不能再次修改特性。
Object.defineProperty(obj,"val",{
value:"hello",
configurable:false
});
//重新修改特性
Object.defineProperty(obj,"val",{
value:"hello",
configurable:true
});
console.log(obj.val); //报错:Uncaught TypeError: Cannot redefine property: val
//configurable设置为false,不能再次修改特性。
Object.defineProperty(obj,"val",{
value:"hello",
configurable:true
});
//重新修改特性
Object.defineProperty(obj,"val",{
value:"hello",
configurable:false
});
console.log(obj.val); //输出hello
现在说说最重要的getter和setter方法,数据绑定的主要方法。
<input type="text" id="val"/>
<span id="bind"></span>
<script>
var obj = {};
Object.defineProperty(obj,'hello',{
set:function(val){
document.getElementById('bind').innerHTML = val;
document.getElementById('val').value = val;
},
get:function () {
console.log('get方法被触发了');
return 3;
}
});
document.getElementById('val').onkeyup = function(e){
obj.hello = e.target.value;
console.log(obj.hello)
};
obj.hello = 999;
</script>
当我们监听input的键盘事件的时候,只要input里面的值改变了,只要obj.hello 赋值,就会触发set方法,这时候我们就可以在里面操作改变页面。只要调用obj.hello,就会触发get方法,这时候打印出来的obj.hello一直等于3,因为我们return的就是3,所以这边应该返回改变的值。这时候估计很多人会觉得都是监听,那还不如直接写在input的监听事件里面,其实不是的,只要你调用了obj.hello,页面的值就会变化。就像obj.hello = 999;那么页面的值就会是999;感兴趣的可以复制代码的方法,一个一个方法调用,就很容易明白原生JS的双向绑定。
欢迎关注 Coding 个人笔记 公众号
网友评论