vue实现双向数据绑定之Object.defineProperty()篇
前言
vue.js中使用ES5的Object.defineProperty()实现数据的双向绑定
Object.defineProperty()原理
Object.defineProperty()可以用来修改对象的属性,也可以在对象上新创建一个属性
语法
Object.defineProperty(obj, prop, descriptor)
参数: obj -> 被定义或修改属性的对象
prop -> 要定义或修改的属性名称
descriptor -> 对属性的描述
返回值
函数将返回传递给他的obj对象本身
描述符(descriptor)说明
该方法允许开发者精确的对对象属性的定义和修改。通过正常赋值进行属性添加而构建的属性会被枚举器方法(如for..in循环或Object.keys方法)获取,从而导致属性值被外部方法改变或删除。而Object.defineProperty()可以避免以上描述的情况,默认的,通过Object.defineProperty()添加的属性是默认不可改变的。
属性描述参数(descriptor)主要由两部分构成:数据描述符(data descriptor)和访问器描述符(accessor descriptor)。数据描述符就是一个包含属性的值,并说明这个值可读或不可读的对象;访问器描述符就是包含该属性的一对getter-setter方法的对象。一个完整的属性描述(descriptor)必须是这两者之一,并且不可以两者都有。
数据描述符
value:属性的值,默认为undefined
writable:可重写性,如果为false,属性的值就不能被重写, 只能为只读了,默认为false
configurable:可配置性,总开关,一旦为false,就不能再设置他的(value,writable,configurable),默认为false
enumerable:可枚举性,是否可枚举(是否能在for...in循环中遍历出来或在Object.keys中列举出来),默认为false
访问器描述符
get:获取数据时触发
set:设置数据时触发
- 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,这里会打印'默认姓名')
vue实现双向数据绑定之Object.defineProperty()篇的更多相关文章
- vue的双向数据绑定实现原理
在目前的前端面试中,vue的双向数据绑定已经成为了一个非常容易考到的点,即使不能当场写出来,至少也要能说出原理.本篇文章中我将会仿照vue写一个双向数据绑定的实例,名字就叫myVue吧.结合注释,希望 ...
- 面试题:你能写一个Vue的双向数据绑定吗?
在目前的前端面试中,vue的双向数据绑定已经成为了一个非常容易考到的点,即使不能当场写出来,至少也要能说出原理.本篇文章中我将会仿照vue写一个双向数据绑定的实例,名字就叫myVue吧.结合注释,希望 ...
- vue实现双向数据绑定的原理
vue实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的. 在MDN上对该方法的说明是:O ...
- 浅析vue的双向数据绑定
vue 的双向数据绑定是基于es5的 object对象的defineProperty属性,重写data的set和get函数来实现的.1.defineProperty 数据展示 Object.defin ...
- Vue基础01vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令
自学vue框架,每天记录重要的知识点,与大家分享!有不足之处,希望大家指正. 本篇将讲述:vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令 前期学习基础,使用vue. ...
- Vue的数据双向绑定和Object.defineProperty()
Vue是前端三大框架之一,也被很多人指责抄袭,说他的两个核心功能,一个数据双向绑定,一个组件化分别抄袭angular的数据双向绑定和react的组件化思想,咱们今天就不谈这种大是大非,当然我也没到达那 ...
- 转 vue实现双向数据绑定之原理及实现篇
转自:https://www.cnblogs.com/canfoo/p/6891868.html vue的双向绑定原理及实现 前言 先上个成果图来吸引各位: 代码: ...
- 17: VUE数据绑定 与 Object.defineProperty
VUE数据绑定原理:https://segmentfault.com/a/1190000006599500?utm_source=tag-newest Object.defineProperty(): ...
- 应用defineProperty简单实现vue的双向数据绑定
双向数据绑定简易版本如何应用defineProperty的getter setter 方法 有这样HTML片段 <input type="text" id="dem ...
随机推荐
- Cesium实现键盘控制镜头效果
w-前进 a-左转 d-右转 s-后退 q-上仰 鼠标左键按住左右移动更换角度 html代码如下: <div id="cesiumContainer" style= ...
- Java抽象类(Abstract Class)与接口(Interface)区别
抽象类与接口比较 抽象类跟接口类似,都不能实例化,可能包含不需实现方法或已实现的方法. 抽象类可以定义一些不是静态或常量的字段,定义 public, protected, private访问级别的具体 ...
- DB2常见错误信息
000 00000 SQL语句成功完成01xxx SQL语句成功完成,但是有警告+012 01545 未限定的列名被解释为一个有相互联系的引用+098 01568 动态SQL语句用分号结束+100 0 ...
- 转:Java中的String,StringBuilder,StringBuffer三者的区别
最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下, ...
- Java 过一下基础
点我跳过黑哥的卑鄙广告行为,进入正文. Java多线程系列更新中~ 正式篇: Java多线程(一) 什么是线程 Java多线程(二)关于多线程的CPU密集型和IO密集型这件事 Java多线程(三)如何 ...
- linux历史命令查找快捷方式
一.回到上次操作的目录# cd -进入上次访问目录 二.历史命令搜索操作快捷键:[Ctrl + r], [Ctrl + p], [Ctrl + n] 在终端中按捉 [Ctrl] 键的同时 [r] ...
- 模拟placeholder
把这个记下来,主要是因为这里的 defaultValue 我之前竟然不知道 <input type="text" value="提示内容" onFocus ...
- 5.02-requests_proxy
import requests # 1.请求url url = 'http://www.baidu.com' headers = { 'User-Agent': 'Mozilla/5.0 (Macin ...
- UVA12558-Efyptian Fractions(HARD version)(迭代加深搜索)
Problem UVA12558-Efyptian Fractions(HARD version) Accept:187 Submit:3183 Time Limit: 3000 mSec Pro ...
- 【转】VMware 14 Pro安装mac os 10.12
一.准备工作 [1]资源下载 VMware Workstation Pro 14 已安装或自行安装 Unlocker (链接: https://pan.baidu.com/s/1dG5jkuH 密码: ...