一、Object.defineProperty是什么?

Object.defineProperty 是ES5Proxy 为开发者提供JavaScript已有却不能调用的功能,在ES5之前,js环境中的对象包含许多不可枚举和可枚举的属性,但是开发者不能自己定义可枚举和不可枚举,于是ES5引入了Object.definePeoperty()方法来支持去做js引擎早就可以实现的事情

1.Object.defineProperty 参数

Object.defineProperty(obj, prop, descriptor)

  1. obj 要定义的对象
  2. prop 要定义或修改的属性的名称或 Symbol
  3. descriptor要定义或修改的属性描述符。

使用 Object.defineProperty() 添加的属性值是不可修改的
代码如下(示例):

let obj = {};let newObj = Object.defineProperty(obj, "OBJ", {value: { a: 1, b: 2, c: 3 },
});obj === newObj // true
newObj.OBJ // { a: 1, b: 2, c: 3 }
//使用 Object.defineProperty() 添加的属性值是不可修改的
newObj.OBJ = 111;
newObj.OBJ // { a: 1, b: 2, c: 3 }
// 不可枚举的

添加的属性值是不可修改的

let obj = {};
let newObj = Object.defineProperty(obj, "b", {value: { a: 1},
});
newObj.b // {a:1}
newObj.b = 123
newObj.b // {a:1}

添加的属性值是不可修改的怎么变为可修改?
当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符改变。
默认为 false。

let obj = {};
let newObj = Object.defineProperty(obj, "b", {value: { a: 1},writable: true,
});
newObj.b // {a:1}
newObj.b = 123
newObj.b // 123

删除属性

let obj = {};
let newObj = Object.defineProperty(obj, "b", {value: { a: 1},
});
delete newObj.OBJ;
newObj.OBJ // { a: 1},

的怎么变为可删除属性?
当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。
默认为 false

let obj = {};
let newObj = Object.defineProperty(obj, "b", {value: { a: 1},configurable :true
});
delete newObj.OBJ;
newObj.OBJ // undefined

delete 操作符可以从对象中删除某个属性,成功返回true,不成功返回false

如果尝试删除不可配置的属性则会抛出异常

'use strict';let target = {name:'target',value:12}Object.defineProperty(target,'name',{configurable:false})
// Uncaught TypeError: Cannot delete property 'name'
log(delete target.name)

Uncaught TypeError: Cannot delete property ‘name’ of #
这个错误在 Proxy 中可以得到解决

枚举和循环Object

let obj = { a: 1, b: 2, c: 3 };
Object.keys(obj) // [a,b,c]
for(let key in obj){console.log(key) //a,b,c
}

禁止枚举和循环Object

let obj = {};let newObj = Object.defineProperty(obj, "OBJ", {enumerable: false,value: { a: 1, b: 2, c: 3 },// enumerable: false,
});console.log(Object.keys(newObj)); // []// 不进,没有迭代属性
for (const key in newObj) {console.log(key);
}

使用get 和set 来监听但前对象的使用
使用get 和set的时候需要注意不能够代理对象的任何属性设置value,和writable 否者会出错 TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #
但是可以添加 enumerable 枚举属性 以及 configurable 是否可以被删除

let obj = {};Object.defineProperty(obj, "a", {get: (data) => {console.log("getget", data);},set: (data) => {console.log("setset", data);},
});obj.a = 1999;obj.a;

一、Proxy是什么?

ES6添加了一些内置的3对象,赋予开发者更多的访问JavaScript引擎的能力,Proxy(代理)是可以拦截并且改变底层JavaScript引擎操作的包装器

Object.defineProperty 基本语法对比Proxy

let obj = {};let neObj = Object.defineProperty(obj,'b',{})console.log(obj === neObj); // true 因为修改的同一个数据源let target = {};let py = new Proxy(target, {});console.log(py == target); //false py 是Proxy代理过的新的 Proxy 对象  target只是一个普通的对象

赋值对比


let target = {};let py = new Proxy(target, {});py.name = "自夏";
target.name = "哥哥";console.log(py.name, target.name); //哥哥 哥哥let obj = {};let neObj = Object.defineProperty(obj, "b", { value: "bbba" });console.log(obj.b, neObj.b); // bbba  bbbaobj.b = "obj.b";
neObj.b = "neObj.b";console.log(obj.b, neObj.b); // bbba bbba

数据劫持 vue3

get(traTarget,key,receiver)
traTarget 代理目标对象
key 要读取属性的key 字符串或者是Symbol
receiver 操作发生的对象

set(traTarget,key ,value,receiver)
traTarget 代理目标对象
key 要写入的属性键(key)字符串或者是Symbol
value 要写入的属性值
receiver 操作发生的对象
deleteProperty(traTarget,propname)
traTarget 代理目标对象
propname 要删除的key

let user = {name:'selfsummer'}let newUser = new Proxy(user,{// 获取数据会触发get(traTarget,key,receiver){console.log(traTarget,key,receiver);return traTarget[key]},// 设置属性值,和添加属性值 会触发set(traTarget,key ,value,receiver){console.log(traTarget,key ,value,receiver);return traTarget[key] = value},// 删除属性deleteProperty(traTarget,propname){console.log(traTarget,propname);return    delete traTarget[propname]}})console.log(newUser.name);console.log(newUser.sex = 'zixia');console.log(newUser.name);delete newUser.name

set

可以拦截写入属性的操作

 const {log} = consolelet user = {name:'selfsummer'}let newUser = new Proxy(user,{// 设置属性值,和添加属性值 会触发set(traTarget,key ,value,receiver){console.log(traTarget,key ,value,receiver);log(isNaN(key),value)// 当前是是存在该对象中if(traTarget.hasOwnProperty(key)){if(isNaN(value)){throw new TypeError('存在修改的属性要修改必须是数字')}}// return traTarget[key] = valuereturn Reflect.set(traTarget,key ,value,receiver)},})newUser.name = 123// newUser.name = '自夏'  错误log(newUser.name) //自夏log(user.name) //自夏newUser.sex = '												

Object.defineProperty 以及 Proxy对比和基本语法 实干vue3数据响应相关推荐

  1. Proxy与Object.defineProperty的优劣对比

    Object.defineProperty 劫持数据 只是对对象的属性进行劫持 无法监听新增属性和删除属性 需要使用 vue.set, vue.delete 深层对象的劫持需要一次性递归 劫持数组时需 ...

  2. es6相关面试题:1.rest参数;2.new.target;3.object.defineProperty与Proxy的区别;4.Reflect对象作用;5.lterator迭代器;6.async

    文章目录 说说对ES6中rest参数的理解 说说你对new.target的理解 谈谈object.defineProperty与Proxy的区别 ES6中的Reflect对象有什么用? 简单介绍下ES ...

  3. Object.defineProperty与proxy进行对比

    Object.defineProperty() 和 ES2015 中新增的 Proxy 对象,会经常用来做数据劫持. 数据劫持:在访问或者修改对象的某个属性时,通过一段代码拦截这个行为,进行额外的操作 ...

  4. Object.defineProperty 和 Proxy 的区别

    Object.defineProperty是一个用来定义对象的属性或者修改对象现有的属性的函数,,而 Proxy 是一个用来包装普通对象的对象的对象. 张子俊改 Object.defineProper ...

  5. Object.defineProperty方法(详解)

    OK,这一篇主要想说一下Object.defineProperty这个方法. 这个方法也是Vue数据双向绑定原理的常见面试题 所以也是有必要好好掌握的哦 首先我们知道JS中是支持面向对象编程的,也是有 ...

  6. Proxy 与 Object.defineProperty 优劣对比

    Proxy的优势如下: Proxy可以直接监听对象而非属性: Proxy可以直接监听数组的变化: Proxy有多达13种拦截方法,不限于apply.ownKeys.deleteProperty.has ...

  7. Vue 的响应式原理中 Object.defineProperty 有什么缺陷?为什么在 Vue3.0 采用了 Proxy,抛弃了 Object.defineProperty?...

    Object.defineProperty无法监控到数组下标的变化,导致通过数组下标添加元素,不能实时响应: Object.defineProperty只能劫持对象的属性,从而需要对每个对象,每个属性 ...

  8. 如何理解JavaScript中Object.defineProperty【一】

    前言 当我们了解一个方法时,建议从以下几个维度着手 1.方法的定义 2.了解方法的使用场景 3.在场景中解决什么问题 带着这样的好奇心,去学习.研究,我们可能更好的理解.掌握.运用它 复制代码 定义 ...

  9. Object.defineProperty也能监听数组变化?

    本文简介 点赞 + 关注 + 收藏 = 学会了 首先,解答一下标题:Object.defineProperty 不能监听原生数组的变化.如需监听数组,要将数组转成对象. 在 Vue2 时是使用了 Ob ...

最新文章

  1. wxWidgets学习 (2) -- 事件处理
  2. java.exe 安装程序_java实现可安装的exe程序实例详解
  3. 有哪些大数据处理工具?
  4. Discuz!NT博客非官方升级!!
  5. BenchmarkDotNet v0.12x新增功能
  6. 深入C#中的String类
  7. iOS-关于cell的重叠问题
  8. 普罗米修斯 监控_新一代的监控系统普罗米修斯(Prometheus)
  9. require js
  10. Mysql编写定时任务事件
  11. eclipse 64位_Eclipse安装教程
  12. MAX脚本发送贴图的另外一个方式
  13. CT一般扫描参数_最实用GE 64排 CT扫描技术请保存、收藏
  14. 性能优化大牛 Brendan Gregg 的新书要来了
  15. 基于ROS2多机器人编程资料
  16. 推荐阅读20100812
  17. 易代账好会计zip导入提示不平衡
  18. 如何在Windows版iTunes中播放Ogg音乐文件
  19. AMD CPU VMware 16 Pro安装macOS 10.15
  20. 如何利用PPT制作九宫格图片效果

热门文章

  1. 一次买房子血淋淋的教训
  2. Android 简单直接--无需jar包zing实现生成、扫描二维码
  3. 回顾码农历程总结2013 期待2014
  4. 4.2.5 Kafka集群与运维(集群的搭建、监控工具 Kafka Eagle)
  5. WinMerge 过滤器的使用方法
  6. java无法验证证书_java – 如何解决“证书无效且无法用于验证此网站的身份”错误?...
  7. 把音频中的某个人声去掉_怎样去掉音频中的背景音乐 只保留人声?
  8. 2020 中秋、国庆快乐!
  9. 利用Scanorama高效整合异质单细胞转录组
  10. 【LeetCode 深度优先搜索专项】不同岛屿的数量 II(711)