这是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. 078_使用 egrep 过滤 MAC 地址

    #!/bin/bash#MAC 地址由 16 进制组成,如 AA:BB:CC:DD:EE:FF#[0-9a-fA-F]{2}表示一段十六进制数值,{5}表示连续出现 5 组前置:的十六进制egrep ...

  2. QVariantMap 和 QVariant

    typedef QVariantMap Synonym for(同义词) QMap<QString, QVariant>. QVariant类型的放入和取出必须是相对应的,你放入一个int ...

  3. luogu P2345 奶牛集会

    二次联通门 : luogu P2345 奶牛集会 /* luogu P2345 奶牛集会 权值线段树 以坐标为下标, 坐标为值建立线段树 对奶牛按听力由小到大排序 对于要查的牛 每次第i次放入奶牛起作 ...

  4. 搭建自己的博客(二十二):通过ajax提交评论信息,并增加公式编辑功能

    编辑功能使用到了ckeditor的MathJax组件.ajax提交评论可以不用刷新浏览器. 1.变化的部分

  5. NetworkX系列教程(6)-对graph进行操作

    小书匠Graph图论 graph生成后,除了有查看操作,还有移除等操作,还有其他更多操作,具体可以看这里.下面将比较graph操作前后的不同. 目录: 7.对图进行操作 7.1移除某些节点和边 7.2 ...

  6. Luogu5072 [Ynoi2015]盼君勿忘 【莫队】

    题目描述:对于一个长度为\(n\)的序列,\(m\)次询问\(l,r,p\),计算\([l,r]\)的所有子序列的不同数之和\(\mathrm{mod} \ p\). 数据范围:\(n,m,a_i\l ...

  7. php语言查询Mysql数据库内容

    通过php语言实现对Mysql数据库的基本操作 1.php页面在进行浏览时需要有php语言执行的环境,本人用的是WampServer软件,只要将项目复制到wampserver_php\wamp\www ...

  8. [游戏开发]imgui介绍

    创建窗口 ImGui::Begin("Hello, world!"); ImGui::End(); 其中, ImGui::Begin("Hello, world!&quo ...

  9. [IMX6DL] CPU频率调节模式以及降频方法

    本文转自http://blog.csdn.net/kris_fei/article/details/51822435 Kernel branch: 3.0.35 CPU的频率调节模式:1. Perfo ...

  10. OpenJudge计算概论-最长单词2

    /*======================================================================== 最长单词2 总时间限制: 1000ms 内存限制: ...