前端如何实现数据双向绑定

Object.defineProperty是ES5中的方法,它可以直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。

语法:

Object.defineProperty(obj, prop, descriptor)

参数:

obj 要在其上定义属性的对象。 prop 要定义或修改的属性的名称。 descriptor 将被定义或修改的属性描述符。 descriptor 可以包含以下属性,默认情况下, writable, enumerable,configurable值为false

value:属性的值 writable:如果为false,属性的值就不能被重写,只能为只读了。 enumerable:是否能枚举,也就是否能在for...in循环中遍历出来或在Object.keys中列举出来。 configurable:如果为false,就不能再设置他的(value,writable,configurable)。 存取描述符同时具有以下可选键值:

get 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法 会被执行,方法执行时没有参数传入,但是会传入this对象

(由于继承关系,这里的this并不一定是定义该属性的对象)。

默认为 undefined。

set 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触 发执行该方法。该方法将接受唯一参数,即该属性新的参数值。

默认为 undefined。

demo:

1.不能变更数据

`var a= {}
 Object.defineProperty(a,"b",{
 value:111
 })
 console.log(a.b);//111
 a.b=3 
 console.log(a.b);//111`
复制代码

2.可以变更数据

` var a= {}
 Object.defineProperty(a,"b",{
 value:111,
 writable:true
 })
 console.log(a.b);//111
 a.b=3 
 console.log(a.b);//3`
复制代码

3.不可以枚举

`Object.defineProperty(a,"b",{
 value:"save", writable:true
 })
 Object.defineProperty(a,"c",{
 value:222, writable:true
 })
 console.log(Object.keys(a)); // []`
复制代码

4.可以枚举

`Object.defineProperty(a,"b",{
 value:"save", writable:true, enumerable:true
 })
 Object.defineProperty(a,"c",{
 value:222, writable:true, enumerable:true
 })
 console.log(Object.keys(a)); // (2) ["c", "b"]
for...in 同Object.keys一样`
复制代码

5.s属性不可以进行配置变更

`Object.defineProperty(a,"s",{
 value:888, writable:true, enumerable:true, configurable:false
 })`
复制代码

6.s属性的writable:false可以重新定义

`Object.defineProperty(a,"s",{
 value:888, writable:false, enumerable:true, configurable:false
 })`
复制代码

7.s属性的除了writable设置为false ,defineProperty变量可以重新定义之外,其它的 value, enumerable, configurable都不可以变更其它内容


`Object.defineProperty(a,"s",{
 value:888, writable:false, enumerable:true, configurable:false
 })`
复制代码

8.set,get属性设置如果设置value和writable会报错,其它属性没关系, configurable为false后get,set之后不能再变更

` Object.defineProperty(a,"s",{
 enumerable:true, configurable:false,get:function(){return this.value},set:function(newdata){ this.value=newdata}
 })`
复制代码

9.继承属性:

如果访问者的属性是被继承的,它的 get 和set 方法会在子对象的属性被访问或者修改时被调用。如果这些方法用一个变量存值,该值会被所有对象共享。

`
function myclass() {
}
var value;
Object.defineProperty(myclass.prototype, "x", {
 get() {
 return value;
 },
 set(x) {
 value = x;
 }
});
var a = new myclass();
var b = new myclass();
a.x = 1;
console.log(b.x); // 1`
复制代码

这可以通过将值存储在另一个属性中固定。在 get 和 set 方法中,this 指向某个被访问和修改属性的对象。

`function myclass() {
}
Object.defineProperty(myclass.prototype, "x", {
 get() {
 return this.stored_x;
 },
 set(x) {
 this.stored_x = x;
 }
});
var a = new myclass();
var b = new myclass();
a.x = 1;
console.log(b.x); // undefined`
复制代码

不像访问者属性,值属性始终在对象自身上设置,而不是一个原型。然而,如果一个不可写的属性被继承,它仍然可以防止修改对象的属性。

`function myclass() {
}
myclass.prototype.x = 1;
Object.defineProperty(myclass.prototype, "y", {
 writable: false,
 value: 1
});
var a = new myclass();
a.x = 2;
console.log(a.x); // 2
console.log(myclass.prototype.x); // 1
a.y = 2; // Ignored, throws in strict mode
console.log(a.y); // 1
console.log(myclass.prototype.y); // 1`
复制代码

双向数据绑定的demo:

`"demo"/>
const dataDemo = {};
const demo = document.getElementById('demo');
Object.defineProperty(dataDemo, 'content', {
 set(value) {
 demo.value = value;
 this.value = value;
 },get(value){ return this.value;}
});
demo.onchange = function(e) {
 dataDemo.content = this.value;
}
console.log(dataDemo.content);
dataDemo.content="双向数据绑定新数据" //input文本框数据会跟着变化`
复制代码

你可能感兴趣的:(前端如何实现数据双向绑定)