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 dialog 异步调用ashx,webservice数据的代码
Aug 03 Javascript
jqPlot 基于jquery的画图插件
Apr 26 Javascript
jquery判断至少有一个checkbox被选中的方法
Jun 05 Javascript
学习javascript面向对象 实例讲解面向对象选项卡
Jan 04 Javascript
javascript跑马灯抽奖实例讲解
Apr 17 Javascript
关于原生js中bind函数的简单实现
Aug 10 Javascript
AngularJS 使用ng-repeat报错 [ngRepeat:dupes]
Jan 19 Javascript
jQuery多选框选择数量限制方法
Feb 08 Javascript
Bootstrap禁用响应式布局的实现方法
Mar 09 Javascript
详解如何在nuxt中添加proxyTable代理
Aug 10 Javascript
移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
Jun 10 Javascript
js找出5个数中最大的一个数和倒数第二大的数实现方法示例小结
Mar 04 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 缓存函数代码
2008/08/27 PHP
PHP base64+gzinflate压缩编码和解码代码
2008/10/03 PHP
探讨Hessian在PHP中的使用分析
2013/06/13 PHP
php实现将wav文件转换成图像文件并在页面中显示的方法
2015/04/21 PHP
浅谈laravel-admin的sortable和orderby使用问题
2019/10/03 PHP
jQuery实现鼠标经过图片预览大图效果
2014/04/10 Javascript
JS折半插入排序算法实例
2015/12/02 Javascript
基于jQuery实现收缩展开功能
2016/03/18 Javascript
深入理解$.each和$(selector).each
2016/05/15 Javascript
jQuery页面加载初始化的3种方法(推荐)
2016/06/02 Javascript
AngularJS创建自定义指令的方法详解
2016/11/03 Javascript
web 屏蔽BackSpace键实例代码
2016/12/24 Javascript
javascript设计模式之Adapter模式【适配器模式】实现方法示例
2017/01/13 Javascript
微信小程序 传值取值的几种方法总结
2017/01/16 Javascript
Vue 2中ref属性的使用方法及注意事项
2017/06/12 Javascript
JavaScript设计模式之单例模式原理与用法实例分析
2018/07/26 Javascript
js限制输入框只能输入数字(onkeyup触发)
2018/09/28 Javascript
详解webpack+ES6+Sass搭建多页面应用
2018/11/05 Javascript
[01:09]DOTA2次级职业联赛 - 99战队宣传片
2014/12/01 DOTA
[01:02:47]EG vs Secret 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
python 查找字符串是否存在实例详解
2017/01/20 Python
对numpy中shape的深入理解
2018/06/15 Python
Python中pandas模块DataFrame创建方法示例
2018/06/20 Python
keras小技巧——获取某一个网络层的输出方式
2020/05/23 Python
美国内衣品牌:Leonisa
2016/08/14 全球购物
Spartoo葡萄牙鞋类网站:线上销售鞋履与时尚配饰
2017/01/11 全球购物
电大物流学生的自我评价
2013/10/25 职场文书
数控机械专业个人的自我评价
2014/01/02 职场文书
商场总经理岗位职责
2014/02/03 职场文书
秋季校运动会广播稿
2014/02/23 职场文书
学习礼仪心得体会
2014/09/01 职场文书
基层党员群众路线教育实践活动个人对照检查材料思想汇报
2014/10/05 职场文书
2016五一劳动节慰问信
2015/11/30 职场文书
使用Redis做预定库存缓存功能
2022/04/02 Redis
详解如何使用Nginx解决跨域问题
2022/05/06 Servers
Redis基本数据类型Zset有序集合常用操作
2022/06/01 Redis