这是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()方法学习笔记的更多相关文章

  1. Object.defineProperties()和Object.defineProperty()方法

    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象. 语法:Object.defineProperty(obj, pro ...

  2. Object.defineProperty方法 使用

    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象. 语法: Object.defineProperty(obj, pr ...

  3. Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象。

    Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象. 语法EDIT Object.defineProperty(obj, ...

  4. JavaScript Object.defineProperty()方法详解

    Object.defineProperty() 方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象. 语法 Object.defineProperty(obj, prop ...

  5. Object 对象方法学习之(1)—— 使用 Object.assign 复制对象、合并对象

    作用 Object.assign() 方法用于把一个或多个源对象的可枚举属性值复制到目标对象中,返回值为目标对象. 语法 Object.assign(target, ...sources) 参数 ta ...

  6. js中Object.defineProperty()方法的解释

    菜菜: “老大,那个, Object.defineProperty 是什么鬼?” 假设我们有个对象 user ; 我们要给它增加一个属性 name , 我们会这么做 1 2 3 var user = ...

  7. Vue el与data的两种写法 && Object.defineProperty方法

    1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8" /> 5 & ...

  8. JavaScript使用Object.defineProperty方法实现双数据绑定

    Object.defineProperty这个方法非常值得学习,很多mvc框架中的双向数据绑定就是通过它来实现的. 本着互联网分享精神,今天我就将我自己的见解分享给大家,希望能有所帮助. 开始使用 O ...

  9. Object.defineProperty 相关学习

    Object.defineProperty 学习   描述: 方法直接在对象上定义一个新属性,或修改对象上的现有属性 并返回该对象.该方法允许精确地添加或修改对象上的属性: 语法: Object.de ...

随机推荐

  1. 49、[源码]-Spring容器创建-创建Bean准备

    49.[源码]-Spring容器创建-创建Bean准备

  2. JsonObject常用转换

    我们在平时的开发中,com.alibaba.fastjson.JSONObject是经常会用到的JSON工具包,同样它的转换方法也会经常被我们使用,包括对象转成JSON串,JSON串转成java对象等 ...

  3. MySQL数据库卸载有残留, windows10 sc delete 拒绝访问 失败5

    sc delete 拒绝访问,原因是当前用户的权限不足,需要做的是在注册表 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\P ...

  4. vue+axios新手实践实现登陆

    vue+axios新手实践实现登陆 https://segmentfault.com/a/1190000015201803 增加 利用HTML5的history.replacestate()修改当前页 ...

  5. luogu 1712

    按区间长度降序排序维护区间指针 [l, r],第 l ~ r 条线段 表示当前区间可以满足条件那么 r 后移一定不是更优的因此 l 前移,使得 r 后移过程中取最小值更新 answer #includ ...

  6. 【テンプレート】字符串hash

    不懂hash是什么的盆友给出直通车:滴滴滴,开车啦~ 如果你看懂了的话: hash模板来也~ #include <cstdio> #include <string> #incl ...

  7. wepy代码知识点

    index-page <style lang="less"> .index-nood-modal { width: 100vw; height: 100vh; posi ...

  8. Java的 「 “ 结构体 ”」 与 「 “ 自定义排序 ” 」

    Java里面的结构体可以靠class来实现,如果相对结构体进行排序,需要写一个接口,class 自定义的名字 implements Comparator<结构体(自己定义的class类的名字)& ...

  9. F 阎小罗的Minimax (第十届山东理工大学ACM网络编程擂台赛 正式赛 )

    题解:by Mercury_Lc 阎小罗的矩阵给的n和m都不超过300,枚举一下所有情况就可以了,用前缀和来储存.数组a[x][y]代表前x行前y列的和是多少,那么枚举每一种切割的方式就可以.注意一下 ...

  10. hbuilder mui html vue ul li 自定义循环赋值ID

    <ul class="mui-table-view mui-table-view-chevron"> <li class="mui-table-view ...