双向数据绑定实现之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()可以 ...
随机推荐
- Matlab带比较方法的快排
首先是主方法QUCIKSORT:(从小到大排列) function [A]=QUICKSORT(A,Low,high,mdat) set(,) if Low<high [A,w]=SPLITIO ...
- SpringCloud IDEA 教学 (三) Eureka Client
写在前头 本篇继续介绍基于Eureka的SpringCloud微服务搭建,回顾一下搭建过程, 第一步:建立一个服务注册中心: 第二步:建立微服务并注入到注册中心: 第三步:建立client端来访问微服 ...
- Thunder团队第三周 - Scrum会议2
Scrum会议2 小组名称:Thunder 项目名称:i阅app Scrum Master:李传康 工作照片: 胡佑蓉在拍照,所以不在照片中. 参会成员: 王航:http://www.cnblogs. ...
- android入门 — PopupWindow
第一步:自定义xml文件 第二步:获取LayoutInflater对象 第三步:调用inflate()方法获取View对象 第四步:创建PopupWindow对象 第五步:调用PopupWindow的 ...
- lintcode-42-最大子数组 II
42-最大子数组 II 给定一个整数数组,找出两个 不重叠 子数组使得它们的和最大. 每个子数组的数字在数组中的位置应该是连续的. 返回最大的和. 注意事项 子数组最少包含一个数 样例 给出数组 [1 ...
- 201621044079 week13 网络
作业13-网络 1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 为了让你的系统可以 ...
- CMD (sea.js)模块定义规范
转自http://www.cnblogs.com/hongchenok/p/3685677.html CMD 模块定义规范 在 Sea.js 中,所有 JavaScript 模块都遵循 CMD(C ...
- Bootstrap 字体图标、下拉菜单、按钮组
Bootstrap 字体图标(Glyphicons) 需要引入fonts文件夹中的文件,而且该文件夹必须命名为fonts,然后引进css文件,jQuery文件,以及bootstrap的js文件. 用法 ...
- 【bzoj4229】选择 离线+LCT
题目描述 现在,我想知道自己是否还有选择. 给定n个点m条边的无向图以及顺序发生的q个事件. 每个事件都属于下面两种之一: 1.删除某一条图上仍存在的边 2.询问是否存在两条边不相交的路径可以从点u出 ...
- POJ3415:Common Substrings——题解
http://poj.org/problem?id=3415 给定两个字符串A 和B,求长度不小于k 的公共子串的个数(可以相同). 论文题,和上道题(POJ2774)类似,首先想到现将AB串合并,然 ...