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 相关文章推荐
在IE模态窗口中自由查看HTML源码的方法
Mar 08 Javascript
javascript检测对象中是否存在某个属性判断方法小结
May 19 Javascript
location.href用法总结(最主要的)
Dec 27 Javascript
js获取下拉列表的值和元素个数示例
May 07 Javascript
浅谈Angular的$q, defer, promise
Dec 20 Javascript
jQuery简单获取DIV和A标签元素位置的方法
Feb 07 Javascript
EsLint入门学习教程
Feb 17 Javascript
jQuery实现的鼠标滚轮控制图片缩放功能实例
Oct 14 jQuery
微信小程序tabbar底部导航
Nov 05 Javascript
Angular2实现的秒表及改良版示例
May 10 Javascript
使用layui实现的左侧菜单栏以及动态操作tab项方法
Sep 10 Javascript
深入浅析React中diff算法
May 19 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实现用户在线时间统计详解
2011/10/08 PHP
关于PHP模板Smarty的初级使用方法以及心得分享
2013/06/21 PHP
PHP 5.5 创建和验证哈希最简单的方法详解
2013/11/07 PHP
PHP中ini_set和ini_get函数的用法小结
2014/02/18 PHP
javascript+php实现根据用户时区显示当地时间的方法
2015/03/11 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
2018/02/08 PHP
jQuery动态设置form表单的enctype值(实现代码)
2013/07/04 Javascript
js动态删除div元素基本思路及实现代码
2014/05/08 Javascript
js星星评分效果
2014/07/24 Javascript
通过JS动态创建一个html DOM元素并显示
2014/10/15 Javascript
nodejs修复ipa处理过的png图片
2016/02/17 NodeJs
JS小数运算出现多为小数问题的解决方法
2016/06/02 Javascript
jQuery的图片轮播插件PgwSlideshow使用详解
2016/08/11 Javascript
浅谈移动端之js touch事件 手势滑动事件
2016/11/07 Javascript
AngularJS使用ng-repeat和ng-if实现数据的删选显示效果示例【适用于表单数据的显示】
2016/12/13 Javascript
JavaScript用JSONP跨域请求数据实例详解
2017/01/06 Javascript
详解Jquery Easyui的验证扩展
2017/01/09 Javascript
vue.js父组件使用外部对象的方法示例
2017/04/25 Javascript
使用Electron构建React+Webpack桌面应用的方法
2017/12/15 Javascript
一文了解Vue中的nextTick
2019/05/06 Javascript
vue多个元素的样式选择器问题
2019/11/29 Javascript
Python中read()、readline()和readlines()三者间的区别和用法
2017/07/30 Python
详解pandas如何去掉、过滤数据集中的某些值或者某些行?
2019/05/15 Python
python3 tkinter实现点击一个按钮跳出另一个窗口的方法
2019/06/13 Python
python实现各种插值法(数值分析)
2019/07/30 Python
用Python爬取QQ音乐评论并制成词云图的实例
2019/08/24 Python
利用python、tensorflow、opencv、pyqt5实现人脸实时签到系统
2019/09/25 Python
HTML5: Web 标准最巨大的飞跃
2008/10/17 HTML / CSS
Lululemon英国官网:加拿大瑜伽服装品牌
2019/01/14 全球购物
成功经营餐厅的创业计划书范文
2013/12/26 职场文书
学生手册评语
2014/05/05 职场文书
2014年学生会主席工作总结
2014/11/07 职场文书
2014年初级职称工作总结
2014/12/08 职场文书
学雷锋感言
2015/08/03 职场文书
纯CSS如何禁止用户复制网页的内容
2021/11/01 HTML / CSS
Spring boot实现上传文件到本地服务器
2022/08/14 Java/Android