【Vue】-- 数据双向绑定的原理 --Object.defineProperty()
Object.defineProperty()方法被许多现代前端框架(如Vue.js,React.js)用于数据双向绑定的实现,当我们在框架Model层设置data时,框架将会通过Object.defineProperty()方法来绑定所有数据,并在数据变化的同时修改虚拟节点,最终修改页面的Dom结构。
一、语法
Object.defineProperty(obj, prop, descriptor)
返回值
二、描述符(descriptor)说明
数据描述符和访问器描述符各自都是对象,有以下键值对:
configurable(必须) |
仅当设置的属性的描述符需要被修改或需要通过delete来删除该属性时,configurable属性设置为true。默认为false。 |
enumerable(必须) |
仅当设置的属性需要被枚举器(如for…in)访问时设置为true。默认为false。 |
value(可选) |
设置属性的值,可以是任何JavaScript值类型(number,object,function等类型)。默认为undefined。 |
writable(可选) |
仅当属性的值可以被赋值操作修改时设置为true。默认为false。 |
访问器描述符可以包含以下可选键值对:
get |
属性的getter方法,若属性没有getter方法则为undefined。该方法的返回为属性的值。默认为undefined |
set |
属性的setter方法,若属性没有setter方法则为undefined。该方法接收唯一的参数,作为属性的新值。默认为undefined。 |
// using __proto__
var obj = {};
var descriptor = Object.create(null); // no inherited properties //所有描述符的属性被设置为默认值
descriptor.value = 'static';
Object.defineProperty(obj, 'key', descriptor); //明确设置每个描述符的属性
Object.defineProperty(obj, 'key', {
enumerable: false,
configurable: false,
writable: false,
value: 'static'
}); //重用同一个对象作为描述符
function withValue(value) {
var d = withValue.d || (
withValue.d = {
enumerable: false,
writable: false,
configurable: false,
value: null
}
);
d.value = value;
return d;
}
Object.defineProperty(obj, 'key', withValue('static')); //如果Object.freeze方法可用,则使用它来防止对对象属性的修改
(Object.freeze || Object)(Object.prototype);
使用示例
创建一个属性
var o = {}; //创建一个对象
//使用数据描述符来为对象添加属性
Object.defineProperty(o, 'a', {
value: 37,
writable: true,
enumerable: true,
configurable: true
});
//属性”a”被设置到对象o上,并且值为37
//使用访问器描述符来为对象添加属性
var bValue = 38;
Object.defineProperty(o, 'b', {
get: function() { return bValue; },
set: function(newValue) { bValue = newValue; },
enumerable: true,
configurable: true
});
o.b; //
//属性”b”被设置到对象o上,并且值为38。
//现在o.b的值指向bValue变量,除非o.b被重新定义
//你不能尝试混合数据、访问器两种描述符
Object.defineProperty(o, 'conflict', {
value: 0x9f91102,
get: function() { return 0xdeadbeef; }
});
//抛出一个类型错误: value appears only in data descriptors, get appears only in accessor descriptors(value只出现在数据描述符中,get只出现在访问器描述符中)
修改一个属性
可写特性-writable
var obj = {};
Object.defineProperty(obj,"name",{
value:"张三",
writable:false//当设置为false的时候当前对象的属性值不允许被修改
})
obj.name="李四"
console.log(obj.name)//张三
var obj = {};
Object.defineProperty(obj,"name",{
value:"张三",
writable:true//当设置为true的时候当前对象的属性值允许被修改
})
obj.name="李四"
console.log(obj.name)//李四
可枚举特性-enumerable
var obj = {name:"张三",age:"李四"}
Object.defineProperty(obj,"name",{
enumerable:false//当设置为false的时候对象的属性不可被枚举
})
Object.defineProperty(obj,"age",{
enumerable:false
})
console.log(Object.keys(obj))//[]
var obj = {name:"张三",age:"李四"}
Object.defineProperty(obj,"name",{
enumerable:true//当设置为true的时候对象的属性可被枚举
})
Object.defineProperty(obj,"age",{
enumerable:true
})
console.log(Object.keys(obj))//["name",age]
可配置特性-configurable
var obj = {};
Object.defineProperty(obj,"name",{
value:"张三",
configurable:false//当设置为false的时候对象的属性不允许被删除
})
delete obj.name;
console.log(obj.name)//张三
var obj = {};
Object.defineProperty(obj,"name",{
value:"张三",
configurable:true//当设置为true的时候对象的属性允许被删除
})
delete obj.name;
console.log(obj.name)//undefined
get和set
Get:指读取属性时调用的函数。
Set:指写入属性时调用的函数
var obj = {name:"张三"}
Object.defineProperty(obj,"name",{
get(){
console.log("被访问了")//当被访问的时候会触发get()方法
},
set(newVal){
console.log("被设置了"+newVal)//当被设置的时候会触发set()方法
}
})
obj.name//输出:被访问了
obj.name="李四";//输出:被设置了李四
添加属性时的默认值
var o = {};
o.a = 1;
//等同于:
Object.defineProperty(o, 'a', {
value: 1,
writable: true,
configurable: true,
enumerable: true
});
//另一方面,
Object.defineProperty(o, 'a', { value: 1 });
//等同于:
Object.defineProperty(o, 'a', {
value: 1,
writable: false,
configurable: false,
enumerable: false
});
configurable和writable
var a={};
Object.defineProperty(a,"o",{
configurable:false,
value:10,
writable:true
});
console.log(a.o);//10
a.o=12;//不报错
console.log(a.o);//12
Object.defineProperty(a,"o",{
configurable:false,
value:14,
writable:true
});
console.log(a.o);//14
Object.defineProperty(a,"o",{
configurable:false,
value:14,
writable:false
});
a.o=16;//不报错
console.log(a.o);//14
//报错
Object.defineProperty(a,"o",{
configurable:false,
value:16,
writable:false
});
【Vue】-- 数据双向绑定的原理 --Object.defineProperty()的更多相关文章
- vue数据双向绑定的原理、虚拟dom的原理
vue数据双向绑定的原理https://www.cnblogs.com/libin-1/p/6893712.html 虚拟dom的原理https://blog.csdn.net/u010692018/ ...
- 西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分
最近我参加了一次来自西安的电话面试(第二轮,技术面),是大厂还是小作坊我在这里按下不表,先来说说这次电面给我留下印象较深的几道面试题,这次先来谈谈Vue的数据双向绑定原理. 情景再现: 当我手机铃声响 ...
- Vue数据双向绑定原理及简单实现
嘿,Goodgirl and GoodBoy,点进来了就看完点个赞再go. Vue这个框架就不简单介绍了,它最大的特性就是数据的双向绑定以及虚拟dom.核心就是用数据来驱动视图层的改变.先看一段代码. ...
- vue数据双向绑定原理
vue的数据双向绑定的小例子: .html <!DOCTYPE html> <html> <head> <meta charset=utf-> < ...
- Vue数据双向绑定原理(vue2向vue3的过渡)
众所周知,Vue的两大重要概念: 数据驱动 组件系统 1 2 接下来我们浅析数据双向绑定的原理 一.vue2 1.认识defineProperty vue2中的双向绑定是基于definePropert ...
- 【学习笔记】剖析MVVM框架,简单实现Vue数据双向绑定
前言: 学习前端也有半年多了,个人的学习欲望还比较强烈,很喜欢那种新知识在自己的演练下一点点实现的过程.最近一直在学vue框架,像网上大佬说的,入门容易深究难.不管是跟着开发文档学还是视频教程,按步骤 ...
- Vue实现双向绑定的原理以及响应式数据
一.vue中的响应式属性 Vue中的数据实现响应式绑定 1.对象实现响应式: 是在初始化的时候利用definePrototype的定义set和get过滤器,在进行组件模板编译时实现water的监听搜集 ...
- vue双向数据绑定的原理-object.defineProperty() 用法
有关双向数据绑定的原理 关于数据双向绑定的理解:利用了 Object.defineProperty() 这个方法重新给对象定义了新属性,在操作新属性分别为为获取属性值(调用get方法)和设置属性值(调 ...
- 深入理解Proxy 及 使用Proxy实现vue数据双向绑定
阅读目录 1.什么是Proxy?它的作用是? 2.get(target, propKey, receiver) 3.set(target, propKey, value, receiver) 4.ha ...
随机推荐
- 如果固定电脑ip地址
打开网络和共享中心 点击详细信息,即可看到IP地址.子网掩码.默认网关.DNS服务器信息 点击本WLAN状态->属性 找到Internet 协议版本 4(TCP/IPv4) 用鼠标左键单击两下 ...
- Redux Counter example
此项目模板是使用Create React App构建的,它提供了一种简单的方法来启动React项目而无需构建配置. 使用Create-React-App构建的项目包括对ES6语法的支持,以及几种非官方 ...
- python 错误捕获机制分析
python语言是编程中使用率在Top 3之内的语言.python语言以灵活与简单著称,那么越是灵活的语言越需要判断出错的功力. 简单示例 以下是一个简单的错误程序,被除数不可为0,那么看看该代码的执 ...
- [Luogu P3295][SCOI 2016]萌萌哒
先说下暴力做法,如果[l1,r1]和[l2,r2]子串相等等价于两个区间内每个数对应相等.那么可以用并查集暴力维护,把对应相等的数的位置维护到同一个集合里去,最后答案其实就是把每个集合可以放的数个数乘 ...
- Resources (being shared)
论文下载求助论坛 数学杂志的模版 答辩PPT模版 发一篇文章的经历 数学期刊名称缩写 英文书籍下载 英文书籍下载 中文书籍下载 数学分析高等代数考研试题官方下载地址
- [物理学与PDEs]第1章习题7 载流线圈的磁场
设一半径为 $R$ 的圆周电路上的电流强度为 $I$. 试计算在通过圆心垂直于圆周所在平面的直线上, 由该圆周电路产生的磁场的磁感强度. 解答: 由对称性知在该直线 $l$ 上, ${\bf B}$ ...
- Spring基础4
一.Spring的JDBC模板 Spring对持久层也提供了解决方案,ORM模块和JDBC模板 提高简化JDBC或Hibernate的模板 二.JDBC模板使用入门 1)引入jar包:Spring开发 ...
- kerbose常用操作
1.查看有那些用户认证 kadmin.local -q "list_principals" 2.用keytab文件进行认证 kinit -kt /root/keytab/hive. ...
- SQL Server - 四种排序, ROW_NUMBER() /RANK() /DENSE_RANK() /ntile() over()
>>>>英文版 (更简洁易懂)<<<< 转载自:https://dzone.com/articles/difference-between-rownum ...
- VOC2012数据集注解
VOC2012官网介绍:http://host.robots.ox.ac.uk/pascal/VOC/voc2012/index.html 分割部分:参考博客:https://blog.csdn.ne ...