前言

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()篇的更多相关文章

  1. vue的双向数据绑定实现原理

    在目前的前端面试中,vue的双向数据绑定已经成为了一个非常容易考到的点,即使不能当场写出来,至少也要能说出原理.本篇文章中我将会仿照vue写一个双向数据绑定的实例,名字就叫myVue吧.结合注释,希望 ...

  2. 面试题:你能写一个Vue的双向数据绑定吗?

    在目前的前端面试中,vue的双向数据绑定已经成为了一个非常容易考到的点,即使不能当场写出来,至少也要能说出原理.本篇文章中我将会仿照vue写一个双向数据绑定的实例,名字就叫myVue吧.结合注释,希望 ...

  3. vue实现双向数据绑定的原理

    vue实现双向数据绑定的原理就是利用了 Object.defineProperty() 这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的. 在MDN上对该方法的说明是:O ...

  4. 浅析vue的双向数据绑定

    vue 的双向数据绑定是基于es5的 object对象的defineProperty属性,重写data的set和get函数来实现的.1.defineProperty 数据展示 Object.defin ...

  5. Vue基础01vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令

    自学vue框架,每天记录重要的知识点,与大家分享!有不足之处,希望大家指正. 本篇将讲述:vue的基本示例,vue的双向数据绑定,vue中常见的几种用法,vue相关常见指令 前期学习基础,使用vue. ...

  6. Vue的数据双向绑定和Object.defineProperty()

    Vue是前端三大框架之一,也被很多人指责抄袭,说他的两个核心功能,一个数据双向绑定,一个组件化分别抄袭angular的数据双向绑定和react的组件化思想,咱们今天就不谈这种大是大非,当然我也没到达那 ...

  7. 转 vue实现双向数据绑定之原理及实现篇

    转自:https://www.cnblogs.com/canfoo/p/6891868.html vue的双向绑定原理及实现 前言 先上个成果图来吸引各位: 代码:                  ...

  8. 17: VUE数据绑定 与 Object.defineProperty

    VUE数据绑定原理:https://segmentfault.com/a/1190000006599500?utm_source=tag-newest Object.defineProperty(): ...

  9. 应用defineProperty简单实现vue的双向数据绑定

    双向数据绑定简易版本如何应用defineProperty的getter setter 方法 有这样HTML片段 <input type="text" id="dem ...

随机推荐

  1. 使用Razor Generator构建模块化ASP.NET MVC应用程序

    在构建Web应用程序的时候,我们很难做到模块化的开发,这是因为Web应用程序不仅仅包含编译的C#代码,还包含了js.css和aspx等资源. 在ASP.NET MVC中,我们发布应用程序的时候,还会包 ...

  2. ES5-ES6-ES7_解构赋值

    解构赋值的概念 ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring) 传统对变量赋值的方式,以前,为变量赋值,只能直接指定值. var a = 1; ...

  3. 微信小程序如何引入外部字体库iconfont的图标

    每天学习一点点 编程PDF电子书.视频教程免费下载:http://www.shitanlife.com/code 微信小程序不能识别很多文件, 其中就包括外部的字体文件. 那我们怎么突破他的防火线呢, ...

  4. java 方法超时

    public void getcd() { logger.info("任务开始!-------------------------------------"); final Exe ...

  5. shut immediate 数据库遭遇 ORA-24324 ORA-24323

    SQL> shut immediateORA-24324: service handle not initializedORA-24323: value not allowedORA-27140 ...

  6. Java-Method类常用方法详解

    一.Method类的定义Method类位于 java.lang.reflect 包中,主要用于在程序运行状态中,动态地获取方法信息二.Method类的常用方法  1.getAnnotatedRetur ...

  7. github 遇到Permanently added the RSA host key for IP address '192.30.252.128' to the list of known hosts问题解决

    刚开始使用github的时候不是很了解,新手一般的都会遇到这个问题Permanently added the RSA host key for IP address '192.30.252.128' ...

  8. Git分支管理规范

    关于Git的一些分支管理规范... 一.分支与角色说明 Git 分支类型 master 分支(主分支) 稳定版本 develop 分支(开发分支) 最新版本 release 分支(发布分支) 发布新版 ...

  9. Linux并发与同步专题 (3) 信号量

    关键词:Semaphore.down()/up(). <Linux并发与同步专题 (1)原子操作和内存屏障> <Linux并发与同步专题 (2)spinlock> <Li ...

  10. Project Tungsten:让Spark将硬件性能压榨到极限(转载)

    在之前的博文中,我们回顾和总结了2014年Spark在性能提升上所做的努力.本篇博文中,我们将为你介绍性能提升的下一阶段——Tungsten.在2014年,我们目睹了Spark缔造大规模排序的新世界纪 ...