vue.js利用Object.defineProperty实现双向绑定


Posted in Javascript onMarch 09, 2017

Object.defineProperty这个方法了不起啊,vue.js是通过它实现双向绑定的。。而且Object.observe也被草案发起人撤回了。。所以defineProperty更有必要了解一下了。

几行代码看他怎么用

var a= {}
Object.defineProperty(a,"b",{
 value:123
})
console.log(a.b);//123

很简单,它接受三个参数,而且都是必填的。。

传入参数

第一个参数:目标对象
第二个参数:需要定义的属性或方法的名字。
第三个参数:目标属性所拥有的特性。(descriptor)

前两个参数不多说了,一看代码就懂,主要看第三个参数descriptor,看看有哪些取值

descriptor

他又以下取值,我们简单认识一下,后面例子,挨个介绍。

  • value:属性的值(不用多说了)
  • writable:如果为false,属性的值就不能被重写,只能为只读了
  • configurable:总开关,一旦为false,就不能再设置他的(value,writable,configurable)
  • enumerable:是否能在for...in循环中遍历出来或在Object.keys中列举出来。
  • get:一会细说
  • set:一会细说

descriptor 默认值

我们再看看第一个例子

var a= {}
Object.defineProperty(a,"b",{
 value:123
})
console.log(a.b);//123

我们只设置了 value,别的并没有设置,但是第一次的时候 可以简单的理解为(暂时这样理解)它会默认帮我们把writable,configurable,enumerable。都设上值,而且值还都是false。。也就是说,上面代码和下面是等价的的(仅限于第一次设置的时候)。

var a= {}
Object.defineProperty(a,"b",{
 value:123,
 writable:false,
 enumerable:false,
 configurable:false
})
console.log(a.b);//123

以上非常重要哦。。并且以上理解对set 和 get 不起作用哦

configurable

总开关,第一次设置 false 之后,,第二次什么设置也不行了,比如说

var a= {}
Object.defineProperty(a,"b",{
 configurable:false
})
Object.defineProperty(a,"b",{
 configurable:true
})
//error: Uncaught TypeError: Cannot redefine property: b

就会报错了。

注意上面讲的默认值。。。如果第一次不设置它会怎样。。会帮你设置为false。。所以。。第二次。再设置他会怎样?。。对喽,,会报错

writable

如果设置为fasle,就变成只读了。

var a = {}; 

Object.defineProperty(o, "b", { 
 value : 123,
 writable : false });

console.log(a.b); // 打印 37
a.b = 25; // 没有错误抛出(在严格模式下会抛出,即使之前已经有相同的值)
console.log(o.a); // 打印 37, 赋值不起作用。

enumerable

属性特性 enumerable 定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举。

var a= {}
Object.defineProperty(a,"b",{
 value:3445,
 enumerable:true
})
console.log(Object.keys(a));// 打印["b"]

改为false

var a= {}
Object.defineProperty(a,"b",{
 value:3445,
 enumerable:false //注意咯这里改了
})
console.log(Object.keys(a));// 打印[]

for...in 类似,不赘述了

set 和 get

在 descriptor 中不能同时设置访问器(get 和 set)和 wriable 或 value,否则会错,就是说想用 get 和 set,就不能用 writable 或 value 中的任何一个。

set 和 get,他俩干啥用的的。

var a= {}
Object.definePrope`请输入代码`rty(a,"b",{
 set:function(newValue){
 console.log("你要赋值给我,我的新值是"+newValue)
 },
 get:function(){
 console.log("你取我的值")
 return 2 //注意这里,我硬编码返回2
 }
})
a.b =1 //打印 你要赋值给我,我的新值是1
console.log(a.b) //打印 你取我的值
     //打印 2 注意这里,和我的硬编码相同的

简单来说,这个 “b” 赋值或者取值的时候会分别触发 set 和 get 对应的函数。

这就是实现observe的关键啊。

下一篇,我会分析vue的observe的实现源码,聊聊自己如何一步一步实现$watch。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery插件制作 表单验证实现代码
Aug 17 Javascript
jQuery 文本框得失焦点的简单实例
Feb 19 Javascript
JavaScript数组和循环详解
Apr 27 Javascript
阻止表单提交按钮多次提交的完美解决方法
May 16 Javascript
JS工作中的小贴士之”闭包“与事件委托的”阻止冒泡“
Jun 16 Javascript
JavaScript中自带的 reduce()方法使用示例详解
Aug 10 Javascript
什么是JavaScript注入攻击?
Sep 14 Javascript
Bootstrap实现的经典栅格布局效果实例【附demo源码】
Mar 30 Javascript
关于JavaScript的单双引号嵌套问题
Aug 20 Javascript
vue-router两种模式区别及使用注意事项详解
Aug 01 Javascript
在Vue中使用CSS3实现内容无缝滚动的示例代码
Nov 27 Vue.js
Ajax实现异步加载数据
Nov 17 Javascript
javascript遍历json对象的key和任意js对象属性实例
Mar 09 #Javascript
微信小程序 五星评价功能的实现
Mar 09 #Javascript
javascript实现数据双向绑定的三种方式小结
Mar 09 #Javascript
jQuery插件HighCharts实现2D柱状图、折线图的组合多轴图效果示例【附demo源码下载】
Mar 09 #Javascript
Vue监听数据对象变化源码
Mar 09 #Javascript
html+javascript+bootstrap实现层级多选框全层全选和多选功能
Mar 09 #Javascript
Node.js常用工具之util模块
Mar 09 #Javascript
You might like
PHP调用三种数据库的方法(3)
2006/10/09 PHP
模仿OSO的论坛(一)
2006/10/09 PHP
探讨PHP函数ip2long转换IP时数值太大产生负数的解决方法
2013/06/06 PHP
PHP共享内存用法实例分析
2016/02/12 PHP
Laravel中Trait的用法实例详解
2016/03/16 PHP
php文件上传及下载附带显示文件及目录功能
2017/04/27 PHP
JavaScript 基础问答三
2008/12/03 Javascript
javascript让setInteval里的函数参数中的this指向特定的对象
2010/01/31 Javascript
基于JQuery的多标签实现代码
2012/09/19 Javascript
js去除空格的12种实用方法
2013/11/08 Javascript
JQuery性能优化的几点建议
2014/05/14 Javascript
jQuery中$.click()无效问题分析
2015/01/29 Javascript
有关easyui-layout中的收缩层无法显示标题的解决办法
2016/05/10 Javascript
Bootstrap Fileinput文件上传组件用法详解
2016/05/10 Javascript
微信小程序支付功能 php后台对接完整代码分享
2018/06/12 Javascript
vue 双向数据绑定的实现学习之监听器的实现方法
2018/11/30 Javascript
JavaScript遍历DOM元素的常见方式示例
2019/02/16 Javascript
js实现列表向上无限滚动
2020/01/13 Javascript
微信小程序后端实现授权登录
2020/02/24 Javascript
浅谈JS for循环中使用break和continue的区别
2020/07/21 Javascript
[47:06]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第一局
2016/03/05 DOTA
[54:45]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 Optic vs OG
2018/04/02 DOTA
Python 检查数组元素是否存在类似PHP isset()方法
2014/10/14 Python
Python中IPYTHON入门实例
2015/05/11 Python
Python简单实现控制电脑的方法
2018/01/22 Python
python 运用Django 开发后台接口的实例
2018/12/11 Python
使用Python轻松完成垃圾分类(基于图像识别)
2019/07/09 Python
Python循环结构的应用场景详解
2019/07/11 Python
Python如何将图像音视频等资源文件隐藏在代码中(小技巧)
2020/02/16 Python
CSS3教程(10):CSS3 HSL声明设置颜色
2009/04/02 HTML / CSS
英国时尚女装购物网站:Missguided
2018/08/23 全球购物
新西兰最大、占有率最高的综合性药房:PharmacyDirect药房中文网
2020/11/03 全球购物
新年主持词
2014/03/27 职场文书
未婚证明书模板
2014/10/08 职场文书
试了下Golang实现try catch的方法
2021/07/01 Golang
Python实现学生管理系统并生成exe可执行文件详解流程
2022/01/22 Python