双向数据绑定实现之Object.defineProperty

vue.js利用的是es5的 defineproperty 特性实现的双向数据绑定,了解一下基本原理。

举例

var person= {};
Object.defineProperty(person, "name", {
  value: ‘张三‘
})
console.log(person.name); // 张三

传参

  • 第一个参数:要设置的目标对象(必填)
  • 第二个参数:需要定义的属性或方法的名称(必填)
  • 第三个参数:目标属性所拥有的特性。(descriptor)(必填)

三个参数都是必填项,重点介绍第三个参数 descriptor

descriptor

  • value:属性的值
  • writable:如果为false,属性的值就不能被重写, 只能为只读了
  • configurable:总开关,一旦为false,就不能再设置他的(value,writable,configurable)
  • enumerable:是否可枚举(是否能在for...in循环中遍历出来或在Object.keys中列举出来)
  • get:一会细说
  • set:一会细说

descriptor 默认值

回头看第一个例子

var person= {};
Object.defineProperty(person, "name", {
  value: ‘张三‘
})
console.log(person.name); // 张三

我们只设置了 value,别的并没有设置

但是第一次的时候 可以简单的理解为(暂时这样理解)它会默认帮我们把writable,configurable,enumerable都设上值,而且值还都是false。

也就是说,上面代码和下面是等价的的(仅限于第一次设置的时候)。

var person = {};
Object.defineProperty(person ,"name",{
  value: ‘张三‘,
  writable :false,
  enumerable: false,
  configurable: false
});
console.log(person.name); // 张三

configurable

总开关,第一次设置 false 之后,,第二次什么设置也不行了,比如说

var person = {};
Object.defineProperty(person,"name",{
  configurable: false
});
Object.defineProperty(person,"name",{
  configurable: true
});
//error: Uncaught TypeError: Cannot redefine property: name

就会报错了。。

注意上面讲的默认值。。。如果第一次不设置它会怎样。。会帮你设置为false。。所以。。第二次。再设置他会怎样?。。对喽,,会报错

writable

如果设置为fasle,就变成只读了。。

var person = {};
Object.defineProperty(person, "name", {
      value : ‘张三‘,
      writable : false   });
console.log(person.name); // 打印 张三
person.name = ‘李四‘; // 没有错误抛出(在严格模式下会抛出,即使之前已经有相同的值)
console.log(person.name); // 打印 张三, 赋值不起作用。

enumerable

属性特性 enumerable 定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举。

var person = {};
Object.defineProperty(person, "name", {
      value : ‘张三‘,
      enumerable: true
  }
);
console.log(Object.keys(person)); // 打印 ["name"]
如果将enumerable改为false, for...in 类似
var person = {};
Object.defineProperty(person, "name", {
      value : ‘张三‘,
      enumerable: false
  }
);
console.log(Object.keys(person)); // 打印 []

set 和 get

在 descriptor 中不能同时设置访问器(get 和 set)和 wriable 或 value,否则会错,就是说想用 get 和 set,就不能用 writable 或 value 中的任何一个。

var person= {};
var temp = [];
Object.defineProperty(person, ‘name‘, {
  set: function(newVal) {
    temp[‘name‘] = newVal;
    console.log(‘为person设置新的姓名:‘ + newVal);
  },
  get: function() {
    var _name =  temp[‘name‘] || ‘默认姓名‘;
    console.log(‘获取person的姓名:‘ +  _name);
    return _name;
  }
});
person.name = ‘张三‘;      // 打印 获取person的姓名:张三
console.log(person.name)  // 打印 获取person的姓名:张三(如果不设置name,这里会打印‘默认姓名‘)

简单来说,这个 “name” 赋值或者取值的时候会分别触发 set 和 get 对应的函数。

作者:杨川宝

原文链接:解析神奇的 Object.defineProperty

进一步学习:vue 源码分析之如何实现 observer 和 watcher

时间: 2024-10-20 08:10:41

双向数据绑定实现之Object.defineProperty的相关文章

MVVM双向绑定实现之Object.defineProperty

随着web应用的发展,直接操作dom的应用已渐行渐远,取而代之的是时下越来越流行的MVVM框架,dom操作几乎绝迹,这里面自然是框架底层封装的结果.MVVM框架的双向数据绑定使开发效率大大提高:然后在实现这些双向数据绑定时,使用ES7原生的Object.observe方法则是完美解决方案,但是遗憾的是该方法目前还是ES7的草案阶段,各浏览器还不支持,目前chrome 36+支持该方法. 既然Object.observe不被支持,但是其替代方案是ECMAScript 262v5带来的新东西Obje

解析Object.defineProperty的作用

vue.js的双向数据绑定就是通过Object.defineProperty方法实现的,俗称属性拦截器. 接下来看一下Object.defineProperty使用方式: Object.defineProperty(obj, prop, descriptor)obj:必需.目标对象 prop:必需.需定义或修改的属性的名字descriptor:必需.目标属性所拥有的特性当修改或定义对象的某个属性的时候,给这个属性添加一些特性: 一.访问器属性 访问器属性是对象中的一种特殊属性,它不能直接在对象中

关于什么是MVVM?几种双向数据绑定的方式

1.什么是MVVM? M:(Model,模型层) 数据模型 数据是后端ajax获取到的 V :(View,视图层)需要把数据展示到页面的html中 VM:(ViewModel,视图模型 V与M连接的桥梁) View和Model是通过ViewModel来进行关联的 View改变了 通过DomListener 注册事件 视图改变了 数据就改变了 数据变化了 视图根据DataBindings发生改变(也就是数据劫持) MVVM实现了数据双向绑定 (数据发生改变以后  VM会监测到数据的改变) 自动的通

vue中实现双向数据绑定原理,使用了Object.defineproperty()方法,方法简单

在vue中双向数据绑定原理,我们一般都是用v-model来实现的 ,但一般在面试话会问到其实现的原理, 方法比较简单,就是利用了es5中的一个方法.Object.defineproperty(),它有三个参数, Object.defineproperty(obj,'val',attrObject), 参数1: obj是属性所在的对象,参数2: 'val',属性名,它是一个string类型,参数3: {}属性所描述的对象 详情可以看Object.defineproperty的文档 下面直接上dem

16、前端知识点--Object.defineProperty 的用法+双向数据绑定原理解析

一.Object.defineProperty 的用法 Object.defineProperty 可以用于给对象添加更新属性. <script> // Object.defineProperty可以用于给对象添加或更新属性. // 它里面有下面三个参数: 给设置属性的对象.设置属性的属性名.以及设置的配置项 // 先声明的一个对象 var obj = {} Object.defineProperty(obj,"name",{ // 这个配置项里面有两个函数,分别是gett

JavaScript使用Object.defineProperty方法实现双数据绑定

Object.defineProperty这个方法非常值得学习,很多mvc框架中的双向数据绑定就是通过它来实现的. 本着互联网分享精神,今天我就将我自己的见解分享给大家,希望能有所帮助. 开始使用 Object.defineProperty接收三个参数 *  目标对象 *  需要要定义的属性名或方法的名字 *  目标属性所拥有的特性 - descriptor (之后讲解下面案例不包括) 代码实例 var User = {}; Object.defineProperty(User, 'info',

Vue双向绑定的关键:Object.defineProperty()

这个方法了不起啊.vue.js和avalon.js 都是通过它实现双向绑定的.而且Object.observe也被草案发起人撤回了.所以defineProperty更有必要了解一下了. 先上几行代码看他怎么用. var obj= {} Object.defineProperty(obj,"age",{ value:123 }) console.log(obj.age);//123 很简单,它接受三个参数,而且都是必填的.. 传入参数 第一个参数:目标对象 第二个参数:需要定义的属性或方

Object.defineProperty() 以及 vue 中双数据绑定的底层原理

Object是在javascript中一个被我们经常使用的类型,而且JS中的所有对象都是继承自Object对象的.虽说我们平时只是简单地使用了Object对象来存储数据,并没有使用到太多其他功能,但是Object对象其实包含了很多很有用的属性和方法,尤其是ES5增加的方法,今天我们先探讨一下Object.defineProperty(). Object.defineProperty 给一个对象添加或者修改属性 返回的是一个对象 语法 Object.defineProperty(obj, prop

vue双向数据绑定原理探究(附demo)

昨天被导师叫去研究了一下vue的双向数据绑定原理...本来以为原理的东西都非常高深,没想到vue的双向绑定真的很好理解啊...自己动手写了一个. 传送门 双向绑定的思想 双向数据绑定的思想就是数据层与UI层的同步,数据再两者之间的任一者发生变化时都会同步更新到另一者. 双向绑定的一些方法 目前,前端实现数据双向数据绑定的方法大致有以下三种: 1.发布者-订阅者模式(backbone.js) 思路:使用自定义的data属性在HTML代码中指明绑定.所有绑定起来的JavaScript对象以及DOM元