【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 ...
随机推荐
- 满汉全席[2-SAT]
题面 对不起我又写了一个板题qvq 和洛谷那道模板题没区别...两样菜至少做一样即可 不过注意define和函数的区别!!! #include <cmath> #include <c ...
- shell实战之日志脱敏
本次实战目标为日志脱敏,将日志目录内的所有文件进行处理,凡是涉及到卡号和密码的信息,一律以“*”号替代,要替代的内容都从对应的标签内获取,本脚本执行目录 drwxr-xr-x 5 root root ...
- NOI真题记录
NOI2001 食物链,拓展域并查集. 炮兵阵地,棋盘状压DP. NOI2002 银河英雄传说,kruskal重构树/带权并查集. 贪吃的九头龙,树形DP. NOI2003 逃学的小孩,树形DP,二次 ...
- Wannafly挑战赛23 T2游戏 SG函数
哎,被卡科技了,想了三个小时,最后还是大佬给我说是\(SG\)函数. \(SG\)函数,用起来很简单,证明呢?(不可能的,这辈子都是不可能的) \(SG\)定理 游戏的\(SG\)函数就是各个子游戏的 ...
- 第三十九篇-RecyclerView的使用
RecyclerView介绍 RecyclerView的出现可以替代ListView,并且比ListView更高级且更具灵活性.如果有数据集合,其中的元素将因用户操作或网络事件而在运行时发生改变,请使 ...
- 友盟冲突解决com.umeng.weixin.handler.UmengWXHandler cannot be cast to com.umeng.socialize.handler.UMWXHandler
删掉一个试试
- Java多线程_复习(更新中!!)
java多线程的常见例子 一.相关知识: Java多线程程序设计到的知识: (一)对同一个数量进行操作 (二)对同一个对象进行操作 (三)回调方法使用 (四)线程同步,死锁问题 (五)线程通信 等等 ...
- maven转gradle ,windows错误重定向
gradle init --type pom --stacktrace > g.log 2>&1
- 第二节:重写(new)、覆写(overwrite)、和重载(overload)
一. 重写 1. 关键字:new 2. 含义:子类继承父类中的普通方法,如果在子类中重写了一个和父类中完全相同的方法,子类中会报警告(问是否显式的隐藏父类的中的方法),如果在子类中的方法前加上new关 ...
- npm常用命令学习(npm install -D,semver版本规范, npm进行版本管理的最佳实践用法)
什么是npm npm有两层含义.一层含义是Node的开放式模块登记和管理系统,网址为npmjs.org.另一层含义是Node默认的模块管理器,是一个命令行下的软件,用来安装和管理Node模块. npm ...