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 ...
随机推荐
- [Angular 8] Lazy loading with dynamic loading syntax
@NgModule({ declarations: [AppComponent, HomeComponent], imports: [ BrowserModule, MatSidenavModule, ...
- linux系列(十四):head命令
1.命令格式: head [参数] [文件] 2.命令功能: head 用来显示档案的开头至标准输出中,默认head命令打印其相应文件的开头10行. 3.命令参数: -q 隐藏文件名 -v 显示文件名 ...
- PHP 多维数组 根据字段排序
这个太常用了,记录下.方便后面用 /** * @param $arr [要排序的数组] * @param $condition [要排序的条件, for array('id'=>SORT_DES ...
- ROStopic 通信方式
操作演示,对 topic 通信方式的理解请看:点击打开链接 开启终端,运行 roscore 新开一个终端(已经安装好(ros-<distro>-ros-tutorials 包,否则运行 ...
- ZR#959
ZR#959 解法: 对于一个询问,设路径 $ (u, v) $ 经过的所有边的 $ gcd $ 为 $ g $,这可以倍增求出. 考虑 $ g $ 的所有质因子 $ p_1, p_2, \cdots ...
- Eclipse中Git的操作
一.工程初始化为本地库 工程→右键→Team→Share Project→Git 点击Finish即可 二.Eclipse 中忽略不必追踪控制的文件 列如: .classpath 文件 .projec ...
- windows 家庭版 开启Hyper-V
windows 家庭版无法开启Hyper-V ,建议升级成专业版.
- DELPHI搭建centos开发环境
DELPHI搭建centos7开发环境 关闭防火墙 搭建开发环境,还是直接关闭LINUX防火墙,省事. 否则,使用到的网络端口号,都要在防火墙开放,麻烦. systemctl disable fire ...
- presto计算日期间隔天数或者小时间隔——date_diff函数使用
“Presto是Facebook最新研发的数据查询引擎,可对250PB以上的数据进行快速地交互式分析.据称该引擎的性能是 Hive 的 10 倍以上.”,亲身用过之后,觉得比hive快了10倍不止. ...
- Apache 后台服务器(主要处理php及一些功能请求 如:中文url) Nginx 前端服务器(利用它占用系统资源少得优势来处理静态页面大量请求) Lighttpd 图片服务器 总体来说,随着nginx功能得完善将使他成为今后web server得主流。
Apache 后台服务器(主要处理php及一些功能请求 如:中文url) Nginx 前端服务器(利用它占用系统资源少得优势来处理静态页面大量请求) Lighttpd 图片服务器 总体来说,随着ngi ...