【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 ...
随机推荐
- 位运算之——按位与(&)操作——(快速取模算法)
学习redis 字典结构,hash找槽位 求槽位的索引值时,用到了 hash值 & sizemask操作, 其后的scan操作涉及扫描顺序逻辑,对同模的槽位 按一定规则扫描! 其中涉及位运算 ...
- Luogu P1654 OSU!
写法和CF235B Let's Play Osu!非常相似.但是这个题厉害就厉害在统计的贡献里面有一个平方的期望,而这个平方的期望和期望的平方是完全不一样的,需要另外统计,逻辑上仔细想一想就会明白. ...
- utf8的大小写敏感性测试及其修改方法
utf8的大小写敏感性测试及其修改方法 # 测试utf8的大小写敏感性及其修改方法 -- 以下是utf8不区分大小写 # 修改数据库: ALTER DATABASE database_name CHA ...
- 关于微信登录授权获取unionid的方法
前言:微信登录授权是目前普遍存在于小程序的,还有一种静默授权方式是微信提供的但是不推荐使用,由于不同设备登录openid是不同的那么我们应该怎样拿到一个唯一的ID呢,下面做分享 wxml代码 < ...
- docker 安装入门
install docker 命令 docker version // docker 版本 docker pull nginx // 拉取nginx docker images // 查看本机dock ...
- LFYZ-OJ ID: 1024 火车站
火车过站 问题描述 火车从始发站(称为第1站)开出,在始发站上车的人数为a,然后到达第2站,在第2站有人上.下车,但上.下车的人数相同,因此在第2站开出时(即在到达第3站之前)车上的人数保持为a人.从 ...
- Django - 模式、简单使用
著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业务对象与数据库的对象(ORM) 视图负责与用户的交 ...
- 如何清理Docker占用的磁盘空间?(转载)
本文转载自https://blog.fundebug.com/2018/01/10/how-to-clean-docker-disk/ , 感谢原作者. 摘要:用了Docker,好处挺多的,但是有一个 ...
- [物理学与PDEs]第2章第4节 激波 4.1 间断连接条件
1. 守恒律方程 $$\bex \cfrac{\p f}{\p t}+\cfrac{\p q}{\p x}=0 \eex$$ 在间断线上应满足 ``间断连接条件'': $$\bex [f]\cfra ...
- 【汇总目录】Git
基础教程 [2019年03月26日] 推送提交(git push) [2019年03月26日] 远程分支 [2019年03月26日] 基本的合并冲突处理 [2019年03月25日] 基本的分支与合并操 ...