简单的理解 Object.defineProperty()
Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。
Object.defineProperty(obj,prop,descriptor)
obj 要在其定义属性的对象
prop 要定义或者修改的属性的名称
descriptor 将被定义或修改的属性描述符
通过Object.defineProperty()为对象定义属性,有两种形式,且不能混合使用,分别为数据描述符,存取描述符。
下面分别描述两者的区别:
数据描述符 -- 特有的两个属性(value,writable)
value 属性值
writable 是否可以改变属性的值。默认为false,不能改变。
let obj = {}
Object.defineProperty(obj, 'name', {
value: 'jack',
writable: false // 不能改变属性的值
})
obj.name = '123'
console.log(obj)// {name: 'jack'}
let obj = {}
Object.defineProperty(obj, 'name', {
value: 'jack',
writable: true // 可以改变属性的值
})
obj.name = '123'
console.log(obj)// {name: 123}
存取描述符 -- 是由一对 getter、setter 函数功能来描述的属性
get:一个给属性提供getter的方法,如果没有getter则为undefined。该方法返回值被用作属性值。默认为undefined。
set:一个给属性提供setter的方法,如果没有setter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认值为undefined。
let obj = {}
let temp = null
Object.defineProperty(obj, 'name', {
get: function (val) {
return temp
// console.log("set方法被调用"+val);
},
set: function (val) {
temp = val
console.log("get方法被调用" + val);
}
})
obj.name = 'chen'
console.log(obj.name) //chen
数据描述符和存取描述都具有以下描述符:
configrable 描述属性是否配置,以及可否删除
enumerable 描述属性是否会出现在for in 或者 Object.keys()的遍历中
configrable
单独设置:configurable: false 不能删除属性、不能重新定义属性
单独设置:configurable: true 能删除属性
同时设置:configurable:true 和 writable:false 可以修改属性值
注意:通过赋值的形式,不可以修改,因为 writable为false
let obj = {}
Object.defineProperty(obj,'name',{
value: 'chen',
configurable: true,
writable: false
})
Object.defineProperty(obj,'name',{
value: 'rose'
})
//通过属性定义的形式可以修改name的属性值
console.log(obj.name)
//通过赋值的形式,不可以修改,因为 writable为false
obj.name = 'JS'
console.log(obj.name)// rose
同时设置:configurable:false 和 writable:true 可以修改属性值
注意:通过赋值的形式,可以修改,因为 writable为true
let obj = {}
Object.defineProperty(obj,'name',{
value: 'chen',
configurable: false,
writable: true
})
Object.defineProperty(obj,'name',{
value: 'rose'
})
//通过属性定义的形式可以修改name的属性值
console.log(obj.name) // rose
//通过赋值的形式,可以修改,因为 writable为 true
obj.name = 'JS'
console.log(obj.name)// JS
configurable 总结:
configurable: false 时,不能删除当前属性,且不能重新配置当前属性的描述符(可以把writable的状态由true改为false,而无法由false改为true),但是在writable: true的情况下,可以改变value的值
configurable: true时,可以删除当前属性,可以配置当前属性所有描述符。
enumerable 看如下代码
let obj = {}
Object.defineProperty(obj,'name',{
value: 'chen',
enumerable: false
}) obj.gender = 'HTML' Object.defineProperty(obj,'age',{
value: '110',
enumerable: true
}) console.log(Object.keys(obj)) //['gender', 'age'] for (let i in obj) {
console.log(i)// gender,age
} console.log(obj.propertyIsEnumerable('name')) // false
console.log(obj.propertyIsEnumerable('gender')) // true
console.log(obj.propertyIsEnumerable('age')) // true
注意:下面代码的区别
let obj = {}
obj.gender = 'HTML' // 等价于下面的代码
Object.defineProperty(obj,'gender',{ // 等于这里
value: 'HTML',
configurable: true,
writable: true,
enumerable:true
}) Object.defineProperty(obj,'age',{ // 等价于下面的代码
value: '120'
})
Object.defineProperty(obj,'age',{ // 等于这里
value: '120',
configurable: false,
writable: false,
enumerable: false
})
不变性
1、对象常量
结合writable: false 和 configurable: false 就可以创建一个真正的常量属性(不可修改,不可重新定义或者删除)
let obj = {}
Object.defineProperty(obj,'name',{
value: 'HTML',
configurable: false,
writable: false,
})
delete obj.name //不可删除
obj.name = 'JS' //不可以重新赋值
//通过赋值,可以添加新属性
obj.gender = 'CSS'
console.log(obj.gender) // CSS
//不可重新定义
Object.defineProperty(obj,'name',{value: 'chen'})// 报错: Cannot redefine property: name
2、禁止扩展
如果你想禁止一个对象添加新属性并且保留已有属性,就可以使用 Object.preventExtensions(...)
禁止扩展片段一:
'use strict'
var obj = {name: 'JS'}
Object.preventExtensions(obj)
obj.gender = 'CSS'
console.log(obj.gender) // Cannot add property gender, object is not extensible
禁止扩展片段二:
var obj = {name: 'JS'}
Object.preventExtensions(obj) // 禁止扩展
// 但是仍然可以进行配置
Object.defineProperty(obj, 'name',{
value: 'HTML',
writable: false,
configurable: false
})
console.log(obj.name) // HTML
//不能进行扩展
obj.gender = 'CSS'
console.log(obj.gender) //undefined
注意:在非严格模式下,创建属性gender会静默失败,在严格模式下,将会抛出异常。
3、密封
Object.seal()会创建一个密封的对象,这个方法实际上会在一个现有对象上调用object.preventExtensions(...)并把所有现有属性标记为configurable:false。
var obj = {
name: 'HTML'
}
Object.seal(obj)
obj.gender = 'CSS'
// 不能扩展属性
console.log(obj.gender)// undefined
// 再次验证
console.log(Object.keys(obj)) // ['name']
// 不能再次配置属性
Object.defineProperty(obj,'name',{ // Cannot redefine property: name
name: 'JS',
configurable: true
})
密封之后不仅不能添加新属性,也不能重新配置或者删除任何现有属性(虽然可以改属性的值)
4、冻结
Object.freeze()会创建一个冻结对象,这个方法实际上会在一个现有对象上调用Object.seal(),并把所有现有属性标记为writable: false,这样就无法修改它们的值。
var obj = {
name: 'HTML'
}
Object.freeze(obj)
obj.name = 'Chen'
// 不可以修改已有属性的值
console.log(obj.name) // HTML
这个方法是可以应用在对象上级别最高的不可变性,它会禁止对于对象本身及其任意直接属性的修改(但是这个对象引用的其他对象是不受影响的)
你可以深度冻结一个对象,具体方法为,首先这个对象上调用Object.freeze()然后遍历它引用的所有对象,并在这些对象上调用Object.freeze()。
但是一定要小心,因为这么做有可能会无意中冻结其他共享对象。
var obj = {
name: 'HTML'
}
Object.freeze(obj)
obj.name = 'Chen'
// 不可以修改已有属性的值
console.log(obj.name) // HTML
简单的理解 Object.defineProperty()的更多相关文章
- 深入理解 Object.defineProperty 及实现数据双向绑定
Object.defineProperty() 和 Proxy 对象,都可以用来对数据的劫持操作.何为数据劫持呢?就是在我们访问或者修改某个对象的某个属性的时候,通过一段代码进行拦截行为,然后进行额外 ...
- 理解 Object.defineProperty
理解 Object.defineProperty 本文写于 2020 年 10 月 13 日 Object.defineProperty 用于在一个对象上定义新的属性或修改现有属性并返回该对象. 什么 ...
- 理解Object.defineProperty()
理解Object.defineProperty() Object.defineProperty() 方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象. 基本语法:Obj ...
- 理解Object.defineProperty函数中的get与set
defineProperty是什么: 该函数可以直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象.通俗理解就是: 给对象添加一个新的属性,或者针对对象里的某些属性,可以给这 ...
- 理解Object.defineProperty的作用
对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值.定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = ...
- [转] 理解Object.defineProperty的作用
对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值.定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = ...
- 《转》理解Object.defineProperty的作用
对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值.定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = ...
- vue之Object.defineProperty()
了解Object.defineProerty()方法 关于Object.defineProperty()方法的解释,理解Object.defineProperty的作用 这篇文章做了很详细的概述 关于 ...
- 20+行代码使用es5 Object.defineProperty 实现简单的watch功能
/** * 一个简单的demo 帮助理解defineProperty,只对Object类型参数有效 */ $watch=function(myObject,callback){ function in ...
随机推荐
- SQLServer创建约束
--创建数据库create database studentson primary( name=stu_data, filename='f:\SQL\stu_data.mdf', s ...
- [hdu6326]Monster Hunter
考虑树是以1为中心的菊花图的情况,也即如何安排打怪兽的顺序 用二元组$(a,b)$来描述怪兽,则对于两个怪兽$(a_{1},b_{1})$和$(a_{2},b_{2})$,交换两者不会影响血量的变化量 ...
- mybatis-批量操作数据(list对象 )
在实际工作中老是忘记 传入的参数和数据库参数名称要一致还是与实体类型一致导致很多笑话发生. 那我还是做个记录吧! dao层: int addRemark(@Param("list" ...
- 整理记录一些好用的随机图API
最近自己博客使用的随机图API有些不稳定,自己又去搜集了一些有意思的随机图API,这里做一个整理记录 注意!!!本文链接最后测试时间----2021年11月21日 主题作者Tagaki的API(有时候 ...
- Codeforces 295D - Greg and Caves(dp)
题意: 给出一个 \(n \times m\) 的矩阵,需对其进行黑白染色,使得以下条件成立: 存在区间 \([l,r]\)(\(1\leq l\leq r\leq n\)),使得第 \(l,l+1, ...
- Atcoder Regular Contest 096 D - Sweet Alchemy(贪心+多重背包)
洛谷题面传送门 & Atcoder 题面传送门 由于再过 1h 就是 NOI 笔试了所以题解写得会略有点简略. 考虑差分,记 \(b_i=c_i-c_{fa_i}\),那么根据题意有 \(b_ ...
- GATK4.1 call SNP
GATK4.0 和之前的版本相比还是有较大的不同,更加趋于流程化. 软件安装 1 wget https://github.com/broadinstitute/gatk/releases/downlo ...
- Excel-vlookup内部能不能用函数?(即内部嵌套函数)
11.vlookup(查找值,目标区域,列序号,FALSE0/TRUE1)内部能不能用函数?(即内部嵌套函数) 总结:只能说有,但不是所有,目前还没有找到规律(唯一的规律是内嵌函数结果值得是符合vlo ...
- TOMCAT 搭建
第一步:下载 软件 和 JDK 第二个:https://www.oracle.com/java/technologies/javase-jdk16-downloads.html 传输到Linux里. ...
- A Child's History of England.31
The English in general were on King Henry's side, though many of the Normans were on Robert's. But t ...