前言

JavaScript 中允许使用一些内部特性来描述属性的特征,本文来总结一下对象内部属性与 Object.defineProperty() 的相关知识。

正文

  1、属性类型

  js中使用某些内部属性来描述属性的特征,比如描述属性是否可以枚举,是否可以修改等特征,我们无法访直接问属性的这些特征,但是可以通过[[]]的方式来将某个特性标识为内部属性。这些内部属性分为数据属性和访问器属性。

  (1)数据属性

  数据属性包含一个保存数据值的位置。值会从这个位置读取,也会写入到这个位置。数据属性有 4个特性描述它们的行为。

  a、[[Configurable]]表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特性,或者能否把数据属性修改为访问器属性,默认 true。

  b、[[Enumerable]]表示能否通过 for-in 循环遍历出属性  默认 true。

  c、[[Writable]]表示能否修改属性的值,默认 true,设置为 false 指改属性只读。

  d、[[Value]]保存这个属性的数据值,读写属性的值都是在这个位置,默认值为 undefined。

  要修改对象默认数据属性,必须使用es5的 Object.defineProperty(),该方法包含三个参数,给其添加属性的对象、属性的名称和一个描述符对象。如下:

    var person = {};
Object.defineProperty(person, "age", {
enumerable: true,
configurable: false,
value: 18
});
console.log(person.age);// 18
delete person.age
console.log(person.age);// 18 Object.defineProperty(person, "height", {
enumerable: false,
value: 50
});
console.log(person);//{age:18,height:50}
for (const key in person) {
console.log(key, person[key]);// age 18
}
Object.defineProperty(person, "name", {
writable: false,
value: "Nicholas"
});
console.log(person.name); // "Nicholas"
person.name = "Greg";
console.log(person.name); // "Nicholas"

  注意:在调用 Object.defineProperty() 时, configurable 、 enumerable 和 writable 的值如果不指定,则都默认为 false 。

  (2)访问器属性

  访问器属性 ==访问器属性不包含数据值,他们包含setter和getter函数,这两个函数并不是必须的

  a、[[Configurable]]表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把数据属性修改为访问器属性,默认 true。

  b、[[Enumerable]]表示能否通过for-in循环遍历出属性  默认 true。

  c、[[Set]]写入属性的函数,默认 undefined。

  d、[[Get]]读取属性的函数,默认 undefined。

  同样,访问器属性是不能直接定义的,必须使用 Object.defineProperty() 。如下:

    var person = { name: "Nicholas", isAdult: true };
Object.defineProperty(person, 'age', {
get: function () {
return this.age
},
set: function (newValue) {
this.isAdult = newValue >= 18 ? true : false
}
});
console.log(person.isAdult);
person.age = 17
console.log(person.isAdult);

  注意:设置了访问器属性之后不能再设置数据属性,比如设置了 set/get  就不能再设置 writable。

  2、补充:内部属性的操作

  (1)一次性定义多个属性

  ECMAScript 提供了 Object.defineProperties() 方法可以通过多个描述符一次性定义多个属性。它接收两个参数:要为之添加或修改属性的对象和另一个描述符对象,其属性与要添加或修改的属性一一对应。这样所有属性都是同时定义的,并且数据属性的configurable 、 enumerable 和 writable 特性值都是 false。
    var person = {}
Object.defineProperties(person, {
'name': {
value: "Nicholas"
},
'isAdult': {
writable: true,
configurable: true,
value: true
},
'age': {
configurable: true,
get() {
return this.age
},
set(newValue) {
this.isAdult = newValue >= 18 ? true : false
}
}
})
console.log(person.isAdult);// true
person.age = 17// 首先到age的set方法,然后访问isAdult的writable属性并修改value值
console.log(person.isAdult);// false

  (2)读取属性的特性   Object.getOwnPropertyDescriptor()获取传入对象给定属性的描述符。Object.getOwnPropertyDescriptors()获取给定对象的全部属性描述符。

    var person = { name: "Nicholas", isAdult: true };
Object.defineProperty(person, 'age', {
get: function () {
return this.age
},
set: function (newValue) {
this.isAdult = newValue >= 18 ? true : false
}
});
var descriptor = Object.getOwnPropertyDescriptor(person, 'age')
console.log(descriptor);
//configurable: false
// enumerable: false
// get: ƒ ()
// set: ƒ (newValue)
console.log(Object.getOwnPropertyDescriptors(person));
// {name:{...},isAdult:{...},age:{...}}

  3、对象内部特性和 Object.defineProperty() 应用

  (1)手写实现 const

    function myConst(key, value) {
window.key = value // 把要定义的key挂载到window下,并赋值value
Object.defineProperty(window, key, {
enumerable: false,
configurable: false,
get: function () {
return value
},
set: function (data) {
if (data !== value) { // 当要对当前属性进行赋值时,则抛出错误!
throw new TypeError('Assignment to constant variable.')
} else {
return value
}
}
})
}
myConst('a', 2)
console.log(a);
a = 3//报错 :Assignment to constant variable.

  (2)手动实现每次访问一个属性时,值加一,使得a==1&&a==2&a==3成为可能

    window.b = 0
Object.defineProperty(window, "a", {
get() {
this.b++
return this.b
},
set(value) {
this.b = value
}
})
if (a == 1 && a == 2 & a == 3) {
console.log("111");
}//111

写在最后

  以上就是本文的全部内容,希望给读者带来些许的帮助和进步,方便的话点个关注,小白的成长之路会持续更新一些工作中常见的问题和技术点。

js--对象内部属性与 Object.defineProperty()的更多相关文章

  1. js对象的属性:数据(data)属性和访问器(accessor)属性

    此文为转载,原文: 深入理解对象的数据属性与访问器属性 创建对象的方式有两种:第一种,通过new操作符后面跟Object构造函数,第二种,对象字面量方式.如下 var person = new Obj ...

  2. C#对象内部属性排序测试

    构建对象: class SortGrid { int indexI; int indexJ; public SortGrid(int x, int y) { indexI = x; indexJ = ...

  3. js对象中属性调用.和[] 两种方式的区别

    JS 调用属性一般有两种方法——点和中括号的方法. 标准格式是对象.属性(不带双引号),注意一点的是:js对象的属性,key标准是不用加引号的,加也可以,特别的情况必须加,如果key数字啊,表达式啊等 ...

  4. 对象内部属性[[Class]]

    1.概述 所有的typeof返回值为‘object’的对象都包含一个内部属性[[Class]],我们将它可以看做内部的分类,而非传统面向对象意义的分类.这个属性无法直接访问,一般通过Object.pr ...

  5. JS对象中属性的增删改查

    对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性 对象的分类:           1.内建对象                 -在ES标准中定义的对象,在任何的ES的实现中都可以 ...

  6. js基础学习之-js对象的属性

    Js属性 1. 设置属性 1)  对象. 2)  对象[‘属性名’] 3)   GetAttribute函数 2. 获取属性 1)  变量=对象. 2)  变量=对象[‘属性名’] 3)  GetAt ...

  7. js对象的属性问题

    ES6之前js的对象的属性只能是字符串, <html> <head> <script type="text/javascript"> var a ...

  8. JS对象或属性的不变性

    提到不变性,不得不提一个概念: 对象常量定义:结合可写性与可配置性可以创建一个真正的常量属性(不可修改.重定义.删除) 不变性可划分为以下几个等级: 1)禁止扩展:Object.preventExte ...

  9. js对象常用属性和方法:复制一个对象,获取一个对象的所有key和所有value的方法

    记录对象的一些实用使用方法及属性 // Object.assign() 多个对象合并 key相同则后面的覆盖前面的 const target = { a: 1, b: 2 }; const sourc ...

随机推荐

  1. [luogu7736]路径交点

    对于两条路径,注意到每一个交点都会改变两者的上下关系,因此两条路径交点的奇偶性,仅取决于两者的起点和终点是否改变了上下关系(改变即为奇数) 类似地,对于整个路径方案,令$p_{i}$为以第一层的$i$ ...

  2. [bzoj4945]游戏

    暴力枚举$2^{d}$表示这d个点中一定不选A或一定不选B(那么就包含了所有情况),然后就对原图跑2-sat即可注意一个细节,如果某一条限制中初始点不合法,就不用管了:如果最终点不合法,那么相当于初始 ...

  3. 使用 kubeadm 部署

    上一章中,我们用 minikube 去搭建单机集群,并且创建 Deployment.Service(在三章中讲解),本篇将介绍利用 kubeadm 部署多节点集群,并学会 安装以及使用 kuberne ...

  4. Dapr初体验之服务调用

    初次理解服务调用 在微服务中,有一个难点就是:如果你想使用各个服务组件,你就得知道不同服务的地址和端口,也就是服务发现. 在传统应用我们是怎么做的?就是在web项目里配置上api地址,如下: 在一个w ...

  5. nothing to commit, working tree clean

    本地git提交代码,没有发现有什么啥情况. 本地代码提交不上去

  6. 【Python】批量给图片增加水印工具

    背景 最近有一些图片需要增加水印,找了一圈也没看见比较好的工具,又不想用破解的PS,干脆自己做了一个GUI工具,有需要的同学自取 功能 支持水印预览 自定义水印文字内容 支持行楷和微软雅黑两种字体 支 ...

  7. CF1610F F. Mashtali: a Space Oddysey

    我们首先发现有如下性质: 我们不妨先随机定向边,那么我们发现无论我们如何翻转边. 都会对其两端的点,造成 \(2 / 4\) 的影响,所以我们发现如果一个点其和他相连的所有边权和为偶数,则我们不能调整 ...

  8. 贪心/构造/DP 杂题选做Ⅱ

    由于换了台电脑,而我的贪心 & 构造能力依然很拉跨,所以决定再开一个坑( 前传: 贪心/构造/DP 杂题选做 u1s1 我预感还有Ⅲ(欸,这不是我在多项式Ⅱ中说过的原话吗) 24. P5912 ...

  9. Codeforces 917D - Stranger Trees(矩阵树定理/推式子+组合意义)

    Codeforces 题目传送门 & 洛谷题目传送门 刚好看到 wjz 在做这题,心想这题之前好像省选前做过,当时觉得是道挺不错的题,为啥没写题解呢?于是就过来补了,由此可见我真是个大鸽子(( ...

  10. 2015百度之星之-IP聚合

    IP聚合  Accepts: 138  Submissions: 293  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 6553 ...