双向数据绑定实现之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
双向数据绑定实现之Object.defineProperty的更多相关文章
- vue双向数据绑定的原理-object.defineProperty() 用法
有关双向数据绑定的原理 关于数据双向绑定的理解:利用了 Object.defineProperty() 这个方法重新给对象定义了新属性,在操作新属性分别为为获取属性值(调用get方法)和设置属性值(调 ...
- vuejs的双向数据绑定实现原理——object.defineproperty()
视图和数据变化绑定 而vue.js主要利用了accessor descriptors的set和get来更新视图,这里看到的这个例子挺好,是一个简单的绑定.对于一个html页面 <div> ...
- MVVM双向绑定实现之Object.defineProperty
随着web应用的发展,直接操作dom的应用已渐行渐远,取而代之的是时下越来越流行的MVVM框架,dom操作几乎绝迹,这里面自然是框架底层封装的结果.MVVM框架的双向数据绑定使开发效率大大提高:然后在 ...
- 【Vue】-- 数据双向绑定的原理 --Object.defineProperty()
Object.defineProperty()方法被许多现代前端框架(如Vue.js,React.js)用于数据双向绑定的实现,当我们在框架Model层设置data时,框架将会通过Object.def ...
- 双向绑定Proxy VS Object.defineProperty
Vue3.0的双向绑定将使用Proxy代替Object.defineProperty,据尤大说,速度提升了1倍. 本文我们来探讨一下Proxy对比Object.defineProperty究竟有哪些优 ...
- vue 数据绑定实现的核心 Object.defineProperty()
vue深入响应式原理 现在是时候深入一下了!Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是普通的 JavaScript 对象.而当你修改它们时,视图会进行更新.这使得状态管理非常简 ...
- JavaScript实现简单的双向数据绑定
什么是双向数据绑定 双向数据绑定简单来说就是UI视图(View)与数据(Model)相互绑定在一起,当数据改变之后相应的UI视图也同步改变.反之,当UI视图改变之后相应的数据也同步改变. 双向数据绑定 ...
- 16、前端知识点--Object.defineProperty 的用法+双向数据绑定原理解析
一.Object.defineProperty 的用法 Object.defineProperty 可以用于给对象添加更新属性. <script> // Object.defineProp ...
- vue实现双向数据绑定之Object.defineProperty()篇
前言 vue.js中使用ES5的Object.defineProperty()实现数据的双向绑定 Object.defineProperty()原理 Object.defineProperty()可以 ...
随机推荐
- Kali信息收集-DNS
1.whois查询 直接在终端输入whois 域名 2.查找dns服务器 (1)host (2)dig (3)nslookup 3.域传输 4.域名枚举 (1)dnsdict6 kali没有集成这款工 ...
- 算法模板の数学&数论
1.求逆元 int inv(int a) { ) ; return (MOD - MOD / a) * inv(MOD % a); } 2.线性筛法 bool isPrime[MAXN]; int l ...
- ZOJ 3689 Digging(DP)
Description When it comes to the Maya Civilization, we can quickly remind of a term called the end o ...
- Python中__name__属性的妙用
在Python中,每一个module文件都有一个built-in属性:__name__,这个__name__有如下特点: 1 如果这个module文件是被别的文件导入的,那么,该__name__属性的 ...
- Python中编码问题:u'\xe6\x97\xa0\xe5\x90\x8d' 类型和 ‘\u559c\u6b22\u4e00\u4e2a\u4eba ’ 转为utf-8的解决办法
相信小伙伴们遇到过类似这样的问题,python2中各种头疼的转码,类似u'\xe6\x97\xa0\xe5\x90\x8d' 的编码,直接s.decode()是无法解决编码问题.尝试了无数办法,都无法 ...
- BER-TLV数据结构
本文是自身在研究学习过程中碰到的问题,整理而成. 为了便于后文的引用说明,先列出一段TLV结构的数据: [6F] 4D │ ├─[] A0000003330101 │ ├─[A5] │ │ ├─[] ...
- 如何取得dbgrid中未保存(post)的值(50分)
比如说处在编辑状态时,想取得当前记录值 Dataset.fields[0].Value 就是当前值:Dataset.fields[0].OldValue 就是原始值. 呵呵,我指得是在编辑时,就是按键 ...
- MVC 枚举 转 SelectListItem
ViewBag.userlevel = new SelectList(Enum.GetNames(typeof(AdminLevels)),"", "", te ...
- arc076 F - Exhausted? (霍尔定理学习)
题目链接 Problem Statement There are M chairs arranged in a line. The coordinate of the i-th chair ($$$1 ...
- BZOJ 1786 配对(DP)
如果我们直接令dp[i][j]为前i个位置第i个位置填j所产生的逆序对的最少数.这样是不满足无后效性的. 但是如果发现对于两个-1,如果前面的-1填的数要大于后面的-1填的数.容易证明把他们两交换结果 ...