前言

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. 【Teradata】 TPT基础知识

     1.TPT Description Teradata Parallel Transporter (TPT) is client software that performs data extract ...

  2. spark program guide

    概述 Spark 应用由driver program 组成,driver program运行用户的主函数,在集群内并行执行各种操作 主要抽象RDD: spark提供RDD,是贯穿整个集群中所有节点的分 ...

  3. Fiddler抓包学习

    今天看到一个抓包笔记, 因为是老早抓包的需求, 后期不用就忘了, 换电脑桌面软件图标都没了, 点开看了一下一脸懵逼... 这是啥...  以后有需要在看一遍吧! Fiddler抓包使用教程-扫盲篇 h ...

  4. centos7下安装docker(19容器架构)

    What,Why,How What:什么是容器? 说起容器大家想到的是什么?      集装箱(container),虚拟机,docker,k8s 1. 没毛病,因为容器与集装箱的英文都可以翻译成co ...

  5. WPF中控件的显示与隐藏

    1.WPF中控件的显示与隐藏的属性是 Visibility,它有3个枚举值 Visible, Hidden 和 Collapsed.其中Visible为可见,而 Hidden 和 Collapsed ...

  6. Armitage攻击winxp——P201421410029

    实验简介 实验所属系列: 安全工具使用 实验对象:本科/专科信息安全专业 相关课程及专业: linux基础.网络安全 实验类别: 实践实验类 预备知识 Armitage基本介绍       Armit ...

  7. jenkins不能执行windows下的命令,cmd可执行。

    1.TortoiseSVN程序在安装时候,选择在windows下的命令行执行,要安装 2.安装后,“C:\Program Files\TortoiseSVN\bin”路径下就存在了命令行的一些指令 3 ...

  8. jenkins+mail邮件配置

    1.配置过程中出现的问题,“501 mail from address must be same as authorization user” 解决方案 2.还有一个问题,在配置jenkins的系统配 ...

  9. 初学Python——进程

    什么是进程? 程序不能单独执行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的过程就叫做进程.进程是操作系统调度的最小单位. 程序和进程的区别在于:程序是储存在硬盘上指令的有序集合,是 ...

  10. Csharp—碎片知识积累

    1.获取应用程序的工作目录 2.将两个字符串组成一个新的路径: 3.MessageBox使用(弹出一个消息框)(第一个参数是消息内容,第二个参数是消息标题,第三个参数是按钮设置,第四个参数是消息内容前 ...