理解Object.defineProperty()

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

基本语法:Object.defineProperty(obj, prop, descriptor)
@param obj 【必须】目标对象
@param prop【必须】新增或修改的属性名字
@param descriptor 属性描述符。
属性描述符 包括两种形式:数据描述符和存取描述符。数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对getter-setter函数功能来描述的属性。
但是该两者不能同时存在,描述符只能是其中之一。

一:数据描述符:
比如如下一个普通对象:

  1. var obj = {
  2. "name": "kongzhi"
  3. };

数据描述符属性如下:

  1. Object.defineProperty(obj, "name", {
  2. configurable: true | false,
  3. enumerable: true | false,
  4. value: '任意类型的值',
  5. writable: true | false
  6. });

下面我们来理解下每个属性的含义:

1. value:
含义: 属性的值,可以是任何类型的值,默认为undefined

1-1 不设置value属性
如下代码:

  1. var obj = {};
  2. Object.defineProperty(obj, "name", {});
  3. console.log(obj.name); // undefined

1-2 设置value属性

  1. // 设置value 代码如下:
  2. var obj = {};
  3. Object.defineProperty(obj, "name", {
  4. value: "kongzhi"
  5. });
  6. console.log(obj.name); // kongzhi

2. writable

含义:属性的值是否可以被重写,true: 可以被重写,false: 不能被重写。默认为false。

2-1 writable设置为false,不能重写,如下代码:

  1. var obj = {};
  2. Object.defineProperty(obj, "name", {
  3. value: "kongzhi",
  4. writable: false
  5. });
  6. // 先打印下值
  7. console.log(obj.name); // kongzhi
  8. // 更改值
  9. obj.name = "longen";
  10. // 再打印下
  11. console.log(obj.name); // kongzhi

2-2 writable设置为true,可以被重写,如下代码:

  1. var obj = {};
  2. Object.defineProperty(obj, "name", {
  3. value: "kongzhi",
  4. writable: true
  5. });
  6. // 先打印下值
  7. console.log(obj.name); // kongzhi
  8. // 更改值
  9. obj.name = "longen";
  10. // 再打印下
  11. console.log(obj.name); // longen

3. enumerable

含义:该属性是否可以被枚举(如:for..in 或 Object.keys()). 如果为true的话,可以被枚举,设置为false的话,不能被枚举,默认为false。

3-1 enumerable被设置为false,不能被枚举,如下代码:

  1. var obj = {};
  2. Object.defineProperty(obj, "name", {
  3. value: "kongzhi",
  4. writable: false,
  5. enumerable: false
  6. });
  7. // 先打印对象一下看看
  8. console.log(obj); // {name: "kongzhi"}
  9.  
  10. // 再枚举对象的属性
  11. for(var attr in obj) {
  12. console.log(attr); // 什么都没有输出 说明不能被枚举
  13. }

3-2 enumerable 设置为true,可以被枚举,如下代码:

  1. var obj = {};
  2. Object.defineProperty(obj, "name", {
  3. value: "kongzhi",
  4. writable: false,
  5. enumerable: true
  6. });
  7. // 先打印对象一下看看
  8. console.log(obj); // {name: "kongzhi"}
  9.  
  10. // 再枚举对象的属性
  11. for(var attr in obj) {
  12. console.log(attr); // 输出 name
  13. }

4. configurable

含义:是否可以删除目标属性或是否可以修改目标属性的特性。如果为true的话,可以被删除或可以修改属性,为false的话,不能删除目标属性或不能修改目标属性,默认为false

4-1 configurable: false, 为false的话,不能删除目标属性或不能修改目标属性。如下代码:

  1. var obj = {};
  2. Object.defineProperty(obj, "name", {
  3. value: "kongzhi",
  4. writable: false,
  5. enumerable: false,
  6. configurable: false
  7. });
  8. // 先打印对象一下看看
  9. console.log(obj); // {name: "kongzhi"}
  10.  
  11. // 删除属性
  12. delete obj.name;
  13. // 重新打印下对象,看是否删除成功了
  14. console.log(obj.name); // kongzhi
  15.  
  16. // 修改属性
  17. obj.name = "longen";
  18. // 重新打印下对象,看是否修改成功了
  19. console.log(obj.name); // kongzhi

4-2 configurable: true, 可以删除目标属性 或 可以修改目标属性,如下代码:

  1. var obj = {};
  2. Object.defineProperty(obj, "name", {
  3. value: "kongzhi",
  4. writable: false,
  5. enumerable: false,
  6. configurable: true
  7. });
  8. // 先打印对象一下看看
  9. console.log(obj); // {name: "kongzhi"}
  10.  
  11. // 删除属性
  12. delete obj.name;
  13. // 重新打印下对象,看是否删除成功了
  14. console.log(obj.name); // undefined
  15.  
  16. // 修改属性
  17. obj.name = "longen";
  18. // 重新打印下对象,看是否修改成功了
  19. console.log(obj.name); // longen

二: 存取器描述
使用存取器描述属性的时候,可以使用如下属性:

  1. var obj = {};
  2. Object.defineProperty(obj, "name", {
  3. enumerable: true | false,
  4. configurable: true | false,
  5. get: function() {} | undefined,
  6. set: function(value) {} | undefined
  7. });

注意:当使用了getter或setter的时候,就不能使用writable和value这两个属性。否则会报错。

getter 是获取属性值的方法。如果没有getter 则默认为 undefined,当我们读取某个属性的时候,其实是在对象内部调用了该方法,该方法必须使用return语句,返回值被作为属性值。
setter 是设置属性的方法。如果没有setter,则默认为undefined,该方法接收一个参数,并将该参数值分配该属性。当我们设置某个属性的时候,实际上在对象的内部调用了该方法。

如下代码是使用getter和setter的代码:

  1. var obj = {};
  2. var initValue = "kongzhi";
  3. Object.defineProperty(obj, "name", {
  4. get: function() {
  5. // 当获取属性值的时候触发的函数
  6. return initValue;
  7. } ,
  8. set: function(value) {
  9. // 当设置值的时候触发的函数
  10. initValue = value;
  11. }
  12. });
  13. // 获取值
  14. console.log(obj.name); // kongzhi
  15.  
  16. // 设置值
  17. obj.name = "longen";
  18. // 打印下
  19. console.log(obj.name); // longen

理解Object.defineProperty()的更多相关文章

  1. 深入理解 Object.defineProperty 及实现数据双向绑定

    Object.defineProperty() 和 Proxy 对象,都可以用来对数据的劫持操作.何为数据劫持呢?就是在我们访问或者修改某个对象的某个属性的时候,通过一段代码进行拦截行为,然后进行额外 ...

  2. 理解 Object.defineProperty

    理解 Object.defineProperty 本文写于 2020 年 10 月 13 日 Object.defineProperty 用于在一个对象上定义新的属性或修改现有属性并返回该对象. 什么 ...

  3. 理解Object.defineProperty函数中的get与set

    defineProperty是什么: 该函数可以直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象.通俗理解就是: 给对象添加一个新的属性,或者针对对象里的某些属性,可以给这 ...

  4. 理解Object.defineProperty的作用

    对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值.定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = ...

  5. [转] 理解Object.defineProperty的作用

    对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值.定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = ...

  6. 《转》理解Object.defineProperty的作用

    对象是由多个名/值对组成的无序的集合.对象中每个属性对应任意类型的值.定义对象可以使用构造函数或字面量的形式: var obj = new Object; //obj = {} obj.name = ...

  7. 简单的理解 Object.defineProperty()

    Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性. Object.defineProperty(obj,prop,descriptor ...

  8. vue之Object.defineProperty()

    了解Object.defineProerty()方法 关于Object.defineProperty()方法的解释,理解Object.defineProperty的作用 这篇文章做了很详细的概述 关于 ...

  9. 浅谈兔兔对Object.defineProperty的理解

    给一个对象定义一个新的属性或者在修改一个对象现有的属性,并返回这个对象 语法: Object.defineProperty(参数1,参数2,参数3) 参数1:目标对象 参数2:要修改或者添加的属性名称 ...

随机推荐

  1. Spring集成Quartz完成定时任务

    在JavaEE系统中,我们经常会用到定时任务,比如每天晚上凌晨之后跑批处理或者是每天某个时刻群发消息等等. 我们可以使用java.util.Timer结合java.util.TimerTask来去完成 ...

  2. NOIP2017-普及组复赛第2题 题解

    Description 图书馆中每本书都有一个图书编码,可以用于快速检索图书,这个图书编码是一个正整数.  每位借书的读者手中有一个需求码,这个需求码也是一个正整数.如果一本书的图书编码恰好以读者的需 ...

  3. openFace 人脸识别框架测试

    openface  人脸识别框架  但个人感觉精度还是很一般 openface的githup文档地址:http://cmusatyalab.github.io/openface/ openface的安 ...

  4. 14. 监视ZooKeeper实例

    ZooKeeper服务可以通过以下两种方式进行监控: 使用一组四个字母的单词命令来监视健康状态 使用ZooKeeper内置的Java管理扩展功能 四个字母的单词命令 ZooKeeper响应一组命令,每 ...

  5. 负载均衡之 nginx

    什么是负载均衡负载均衡(Load Balance)是分布式系统架构设计中必须考虑的因素之一,它通常是指,将请求/数据[均匀]分摊到多个操作单元上执行,负载均衡的关键在于[均匀].在使用nginx负载均 ...

  6. 数据库索引------B-Tree 索引和 Hash 索引的对比

    对于 B-tree 和 hash 数据结构的理解能够有助于预测不同存储引擎下使用不同索引的查询性能的差异,尤其是那些允许你选择 B-tree 或者 hash 索引的内存存储引擎. B-Tree 索引的 ...

  7. NOIP2017普及组初赛解析

    首发于订阅号 嗨编程,这是一个以嗨为目标的编程订阅号(仅仅是目标而已),扫码可关注,不定期更.

  8. ElasticSearch 学习记录之 分布式文档存储往ES中存数据和取数据的原理

    分布式文档存储 ES分布式特性 屏蔽了分布式系统的复杂性 集群内的原理 垂直扩容和水平扩容 真正的扩容能力是来自于水平扩容–为集群添加更多的节点,并且将负载压力和稳定性分散到这些节点中 ES集群特点 ...

  9. C# (using Newtonsoft.Json) Json 转换用法小总结

    //序列化 string Json字符串 = JsonConvert.SerializeObject(目标对象); // 字符串转化为对象 string UserJson = "{\&quo ...

  10. inotify软件部署及实时同步

    声明:博主使用的是CentOS6.9的系统 参考资料: https://github.com/rvoicilas/inotify-tools/wiki http://www.ibm.com/devel ...