Object.defineProperty()方法学习笔记
这是js中一个非常重要的方法,ES6中某些方法的实现依赖于它,VUE通过它实现双向绑定
此方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象
参数
Object.defineProperty(object, attribute, descriptor)
这三个参数都是必输项
第一个参数为目标对象
第二个参数为需要定义的属性或者方法
第三个参数为目标属性所拥有的特性
前两个参数都很明确,重点是第三个参数 descriptor, 它有以下取值
descriptor
value: 属性的值
writable: 属性的值是否可被重写(默认为false)
configurable: 总开关,是否可配置,若为false, 则其他都为false(默认为false)
enumerable: 属性是否可被枚举(默认为false)
get: 获取该属性的值时调用
set: 重写该属性的值时调用
一个例子
var a= {}
Object.defineProperty(a,"b",{
value:123
})
console.log(a.b) //
a.b = 456
console.log(a.b) //
a.c = 110
for (item in a) {
console.log(item, a[item]) //c 110
}
因为 writable 和 enumerable 默认值为 false, 所以对 a.b 赋值无效,也无法遍历它
configurable
总开关,是否可配置,设置为 false 后,就不能再设置了,否则报错, 例子
var a= {}
Object.defineProperty(a,"b",{
configurable:false
})
Object.defineProperty(a,"b",{
configurable:true
})
//error: Uncaught TypeError: Cannot redefine property: b
writable
是否可重写
var a = {};
Object.defineProperty(a, "b", {
value : 123,
writable : false
});
console.log(a.b); // 打印 123
a.b = 25; // 没有错误抛出(在严格模式下会抛出,即使之前已经有相同的值)
console.log(a.b); // 打印 123, 赋值不起作用。
enumerable
属性特性 enumerable 定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举
var a= {}
Object.defineProperty(a,"b",{
value:3445,
enumerable:true
})
console.log(Object.keys(a));// 打印["b"]
enumerable改为false
var a= {}
Object.defineProperty(a,"b",{
value:3445,
enumerable:false //注意咯这里改了
})
console.log(Object.keys(a));// 打印[]
set 和 get
如果设置了 set 或 get, 就不能设置 writable 和 value 中的任何一个,否则报错
var a = {}
Object.defineProperty(a, 'abc', {
value: ,
get: function() {
return value
}
})
//Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute, #<Object> at Function.defineProperty
对目标对象的目标属性 赋值和取值 时, 分别触发 set 和 get 方法
var a = {}
var b = 1
Object.defineProperty(a,"b",{
set:function(newValue){
b = 99;
console.log("你要赋值给我,我的新值是"+newValue);
},
get:function(){
console.log("你取我的值");
return 2 //注意这里,我硬编码返回2
}
})
a.b = 1 //打印 你要赋值给我,我的新值是1
console.log(b) //打印 99
console.log(a.b) //打印 你取我的值
//打印 2 注意这里,和我的硬编码相同的
上面的代码中,给a.b赋值,b的值也跟着改变了。原因是给a.b赋值,自动调用了set方法,在set方法中改变了b的值。vue双向绑定的原理就是这个。
扩展
Reflect.defineProperty()
可以使用ES6的静态方法 Reflect.defineProperty(), 使用起来和 Object.defineProperty 完全一样,唯一的不同是修改属性的配置出错时,返回false, 不抛错。 例子:
var a = {}
Reflect.defineProperty(a, "b", {
value: ,
configurable: false
})
Reflect.defineProperty(a, "b", {
value: ,
configurable: true
})
// 返回false
var a = {}
Reflect.defineProperty(a, "b", {
value: 2,
configurable: false
})
Object.defineProperty(a, "b", {
value: 2,
configurable: true
})
//Uncaught TypeError: Cannot redefine property: b at Function.defineProperty (<anonymous>) at <anonymous>:6:8
Object.defineProperties
此方法可以一次设置多个属性,例子:
var a = {}
Object.defineProperties(a, {
c: {
value: 1
},
d: {
value: 2
}
})
// 返回{c: 1, d: 2}
用Object.defineProperty实现黑科技
使 a==1 && a==2 && a==3 为true
var b = 1
Object.defineProperty(window, "a", {
get: function() {
return b++
}
})
console.log(a==1 && a==2 && a==3) //返回true
除此之外,还可以用对象的 toString() 方法来实现
var a = {
b: 1,
toString() {
return this.b++
}
}
console.log(a==1 && a==2 && a==3) //返回true
ps: 这是本人在博客园写的第一个博客,欢迎大家多对支持和提出意见建议
参考:https://www.cnblogs.com/weiqu/p/5860945.html
Object.defineProperty()方法学习笔记的更多相关文章
- Object.defineProperties()和Object.defineProperty()方法
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象. 语法:Object.defineProperty(obj, pro ...
- Object.defineProperty方法 使用
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象. 语法: Object.defineProperty(obj, pr ...
- Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象. 语法EDIT Object.defineProperty(obj, ...
- JavaScript Object.defineProperty()方法详解
Object.defineProperty() 方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象. 语法 Object.defineProperty(obj, prop ...
- Object 对象方法学习之(1)—— 使用 Object.assign 复制对象、合并对象
作用 Object.assign() 方法用于把一个或多个源对象的可枚举属性值复制到目标对象中,返回值为目标对象. 语法 Object.assign(target, ...sources) 参数 ta ...
- js中Object.defineProperty()方法的解释
菜菜: “老大,那个, Object.defineProperty 是什么鬼?” 假设我们有个对象 user ; 我们要给它增加一个属性 name , 我们会这么做 1 2 3 var user = ...
- Vue el与data的两种写法 && Object.defineProperty方法
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8" /> 5 & ...
- JavaScript使用Object.defineProperty方法实现双数据绑定
Object.defineProperty这个方法非常值得学习,很多mvc框架中的双向数据绑定就是通过它来实现的. 本着互联网分享精神,今天我就将我自己的见解分享给大家,希望能有所帮助. 开始使用 O ...
- Object.defineProperty 相关学习
Object.defineProperty 学习 描述: 方法直接在对象上定义一个新属性,或修改对象上的现有属性 并返回该对象.该方法允许精确地添加或修改对象上的属性: 语法: Object.de ...
随机推荐
- 078_使用 egrep 过滤 MAC 地址
#!/bin/bash#MAC 地址由 16 进制组成,如 AA:BB:CC:DD:EE:FF#[0-9a-fA-F]{2}表示一段十六进制数值,{5}表示连续出现 5 组前置:的十六进制egrep ...
- QVariantMap 和 QVariant
typedef QVariantMap Synonym for(同义词) QMap<QString, QVariant>. QVariant类型的放入和取出必须是相对应的,你放入一个int ...
- luogu P2345 奶牛集会
二次联通门 : luogu P2345 奶牛集会 /* luogu P2345 奶牛集会 权值线段树 以坐标为下标, 坐标为值建立线段树 对奶牛按听力由小到大排序 对于要查的牛 每次第i次放入奶牛起作 ...
- 搭建自己的博客(二十二):通过ajax提交评论信息,并增加公式编辑功能
编辑功能使用到了ckeditor的MathJax组件.ajax提交评论可以不用刷新浏览器. 1.变化的部分
- NetworkX系列教程(6)-对graph进行操作
小书匠Graph图论 graph生成后,除了有查看操作,还有移除等操作,还有其他更多操作,具体可以看这里.下面将比较graph操作前后的不同. 目录: 7.对图进行操作 7.1移除某些节点和边 7.2 ...
- Luogu5072 [Ynoi2015]盼君勿忘 【莫队】
题目描述:对于一个长度为\(n\)的序列,\(m\)次询问\(l,r,p\),计算\([l,r]\)的所有子序列的不同数之和\(\mathrm{mod} \ p\). 数据范围:\(n,m,a_i\l ...
- php语言查询Mysql数据库内容
通过php语言实现对Mysql数据库的基本操作 1.php页面在进行浏览时需要有php语言执行的环境,本人用的是WampServer软件,只要将项目复制到wampserver_php\wamp\www ...
- [游戏开发]imgui介绍
创建窗口 ImGui::Begin("Hello, world!"); ImGui::End(); 其中, ImGui::Begin("Hello, world!&quo ...
- [IMX6DL] CPU频率调节模式以及降频方法
本文转自http://blog.csdn.net/kris_fei/article/details/51822435 Kernel branch: 3.0.35 CPU的频率调节模式:1. Perfo ...
- OpenJudge计算概论-最长单词2
/*======================================================================== 最长单词2 总时间限制: 1000ms 内存限制: ...