【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 ...
随机推荐
- Magento 架构原则
Magento架构原则 >OOP体系结构和编程原则OOP体系结构和编程原则面向对象编程(OOP)设计允许软件组件具有最大的灵活性和可扩展性,允许您设计和实现高度定制的网站.面向对象原则的优点包括 ...
- 洛谷P3205 [HNOI2011]合唱队 DP
原题链接点这里 今天在课上听到了这个题,听完后觉得对于一道\(DP\)题目来说,好的状态定义就意味着一切啊! 来看题: 题目描述 为了在即将到来的晚会上有更好的演出效果,作为AAA合唱队负责人的小A需 ...
- html页面中引入自签名证书的js web资源出现net::ERR_CERT_AUTHORITY_INVALID
其实是浏览器客户端对自签名的内容认为不安全引起的,临时方法可以再浏览器中先直接访问下那个自签名的https地址,然后再访问有引用的那个页面就可以了. 以下内容引用自https://www.morong ...
- 【GDOI2016模拟3.16】幂(容斥 + 模型复杂转化)
[GDOI2016模拟3.16]幂 \(X\in[1,A],Y\in[1,B]\),问:\(x^y\)的不用取值个数. \(A,B\)都是\(10^9\)级别. 然后我们开搞. 首先,假设一个合法的\ ...
- python 学习地址
本章主要记录学习python过程中借鉴的一些网站,并感谢这些博主辛勤付出. python官网:https://www.python.org/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- C# 执行DOS命令和批处理
在项目开发中,有时候要处理一些文件,比如视频格式的转换,如果用C开发一套算法,再用C#调用,未免得不偿失!有时候调用现有的程序反而更加方便.今天就来说一下C#中如何调用外部程序,执行一些特殊任务. 这 ...
- ACM-ICPC 2018 沈阳赛区网络预赛 I Lattice's basics in digital electronics(模拟)
https://nanti.jisuanke.com/t/31450 题意 给出一个映射(左为ascll值),然后给出一个16进制的数,要求先将16进制转化为2进制然后每9位判断,若前8位有奇数个1且 ...
- Linux 下软件的安装方法
1:rpm 安装 ,rpm安装会有依赖问题,例如安装A,提示需要安装B 安装B需要安装C 格式: rpm -ivh [包名].rpm 2:yum 安装 特点:简单.易用.高校 缺点:不能定制 解决 ...
- 通俗易懂的vuex-demo
在main.js引入store.js
- 【归纳】正则表达式及Python中的正则库
正则表达式 正则表达式30分钟入门教程 runoob正则式教程 正则表达式练习题集(附答案) 元字符\b代表单词的分界处,在英文中指空格,标点符号或换行 例子:\bhi\b可以用来匹配hi这个单词,且 ...