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

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

  1. vue双向数据绑定的原理-object.defineProperty() 用法

    有关双向数据绑定的原理 关于数据双向绑定的理解:利用了 Object.defineProperty() 这个方法重新给对象定义了新属性,在操作新属性分别为为获取属性值(调用get方法)和设置属性值(调 ...

  2. vuejs的双向数据绑定实现原理——object.defineproperty()

    视图和数据变化绑定 而vue.js主要利用了accessor descriptors的set和get来更新视图,这里看到的这个例子挺好,是一个简单的绑定.对于一个html页面 <div> ...

  3. MVVM双向绑定实现之Object.defineProperty

    随着web应用的发展,直接操作dom的应用已渐行渐远,取而代之的是时下越来越流行的MVVM框架,dom操作几乎绝迹,这里面自然是框架底层封装的结果.MVVM框架的双向数据绑定使开发效率大大提高:然后在 ...

  4. 【Vue】-- 数据双向绑定的原理 --Object.defineProperty()

    Object.defineProperty()方法被许多现代前端框架(如Vue.js,React.js)用于数据双向绑定的实现,当我们在框架Model层设置data时,框架将会通过Object.def ...

  5. 双向绑定Proxy VS Object.defineProperty

    Vue3.0的双向绑定将使用Proxy代替Object.defineProperty,据尤大说,速度提升了1倍. 本文我们来探讨一下Proxy对比Object.defineProperty究竟有哪些优 ...

  6. vue 数据绑定实现的核心 Object.defineProperty()

    vue深入响应式原理 现在是时候深入一下了!Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是普通的 JavaScript 对象.而当你修改它们时,视图会进行更新.这使得状态管理非常简 ...

  7. JavaScript实现简单的双向数据绑定

    什么是双向数据绑定 双向数据绑定简单来说就是UI视图(View)与数据(Model)相互绑定在一起,当数据改变之后相应的UI视图也同步改变.反之,当UI视图改变之后相应的数据也同步改变. 双向数据绑定 ...

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

    一.Object.defineProperty 的用法 Object.defineProperty 可以用于给对象添加更新属性. <script> // Object.defineProp ...

  9. vue实现双向数据绑定之Object.defineProperty()篇

    前言 vue.js中使用ES5的Object.defineProperty()实现数据的双向绑定 Object.defineProperty()原理 Object.defineProperty()可以 ...

随机推荐

  1. SpringCloud IDEA 教学 (五) 断路器控制台(HystrixDashboard)

    写在开头 断路器控制台是为了查看断路器运行情况而研发的.本章介绍了断路器控制台的搭建,代码基于之前Client的搭建.HystrixDashboard基于之前配置好的,使用了HystrixComman ...

  2. jquery中的$(document).ready()、JavaScript中的window.onload()以及body中的onload()、DomContentLoaded()区别

    $().ready().$(handler).$(document).ready(handler)均不是原生JS中的,都是jQuery中封装的方法.这些事件在当页面的dom节点加载完毕后就执行,无需等 ...

  3. Java中的增强for循环

    增强 for 循环 1. 增强的 for 循环对于遍历 Array 或 Collection 的时候相当方便. import java.util.*; public class Test { publ ...

  4. Python 元组 集合

    1. 元组 >>> a = (1,2,3,4,5) >>> b = list(a) #转换成列表对象, 可以更改 >>> b [1, 2, 3, ...

  5. win7 x64+iis7.5 配置错误:CS0016: 未能写入输出文件“c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\7cb4f3

    解决方法: 1. 将windows/temp属性-安全-高级 添加IIS_USERS用户,同时编辑权限为完全控制(写入和编辑)即可. 注意: 要确保权限添加上了,win7下有可能系统为安全,会自动取消 ...

  6. lol人物模型提取(五)

      修改了发过去后,那边说吊坠的绳子太细了,厚度至少1mm,推荐是2mm,需要我自己加粗,没办法又得用3ds max一根一根线地缩放了.   修改好后问报价,高精度树脂打印需要730元,还不带上色的, ...

  7. CentOS修改DNS、IP地址、网关

    一.CentOS 修改DNS 修改对应网卡的DNS的配置文件 # vi /etc/resolv.conf 修改以下内容 nameserver 8.8.8.8 #google域名服务器 nameserv ...

  8. C# 开发者最经常犯的 8 个错误

    在和C#新手一起工作的时候,我注意到他们经常重复一些错误.这些错误,当你指出来的时候很容易理解.然而,如果一个开发者没有意识到这些错误,将会影响正在开发的软件的质量和效率,因此,我决定总结8个常见的错 ...

  9. Shel脚本学习—反引号、单引号、双引号区别与联系

    反引号 反引号位 (`) 位于键盘的Tab键的上方.1键的左方.注意与单引号(')位于Enter键的左方的区别. 在Linux中起着命令替换的作用.命令替换是指shell能够将一个命令的标准输出插在一 ...

  10. BZOJ4245 ONTAK2015 OR-XOR(贪心)

    贪心的按位考虑.如果所有数在某一位上有奇数个为1,显然无论如何划分这一位最终都会为1:否则将每一部分都划分为偶数个1就能保证最终该位为0,可以标记上哪些位置可以作为划分点(当然也要满足之前可为0的位上 ...