1. Object.defineProperty()

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

备注:应当直接在 Object 构造器对象上调用此方法,而不是在任意一个 Object 类型的实例上调用。

语法:

Object.defineProperty(obj, prop, descriptor)

obj

要定义属性的对象。

prop

要定义或修改的属性的名称或 Symbol 。

descriptor

要定义或修改的属性描述符。

例子

在我们平常的使用中,给对象添加一个属性时,直接使用object.param的方式就可以了,或者直接在对象中挂载。

const person = {name: 'hj'
}

在ECMAScript5中,对每个属性都添加了几个属性类型,来描述这些属性的特点。他们分别是

  • configurable:   默认false

configurable 特性表示对象的属性是否可以被删除,以及除 value 和 writable 特性外的其他特性是否可以被修改。

当第一次设置为false后,再改写是不可以的。属性值也是不能被删除的。

var o = {};
Object.defineProperty(o, 'a', {get() { return 1; },configurable: false
});
// 定义为false 后  enumerable set get configurable value 都是不能再设置了。 delete o.a 也是删不了的
Object.defineProperty(o, 'a', {configurable: true
}); // throws a TypeError  抛出错误
Object.defineProperty(o, 'a', {enumerable: true
}); // 抛出错误
Object.defineProperty(o, 'a', {set() {}
}); // 报错
Object.defineProperty(o, 'a', {get() { return 1; }
}); // throws a TypeError
// (even though the new get does exactly the same thing)
Object.defineProperty(o, 'a', {value: 12
}); // throws a TypeError // ('value' can be changed when 'configurable' is false but not in this case due to 'get' accessor)console.log(o.a); // logs 1
delete o.a; // Nothing happens
console.log(o.a); // logs 1  还存在说明没删掉
  • enumerable:  默认false

enumerable 定义了对象的属性是否可以在 for...in 循环和 Object.keys() 中被枚举。

for...in 循环和 Object.keys()  定义: 任意顺序遍历一个对象的除Symbol以外的可枚举属性。

var o = {};
Object.defineProperty(o, "a", { value : 1, enumerable: true });
Object.defineProperty(o, "b", { value : 2, enumerable: false });
Object.defineProperty(o, "c", { value : 3 }); // enumerable 默认为 false
o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则 enumerable 为 true
Object.defineProperty(o, Symbol.for('e'), {value: 5,enumerable: true
});
Object.defineProperty(o, Symbol.for('f'), {value: 6,enumerable: false
});for (var i in o) {console.log(i);
}
// 只会打印a 和 d Object.keys(o); // ['a', 'd']

打印 对象 o 在谷歌浏览器中查看

o.propertyIsEnumerable('a'); // true
o.propertyIsEnumerable('b'); // false
o.propertyIsEnumerable('c'); // false
o.propertyIsEnumerable('d'); // true
o.propertyIsEnumerable(Symbol.for('e')); // true
o.propertyIsEnumerable(Symbol.for('f')); // falsevar p = { ...o }
p.a // 1
p.b // undefined
p.c // undefined
p.d // 4
p[Symbol.for('e')] // 5
p[Symbol.for('f')] // undefined
  • writable:  默认false

当 writable 属性设置为 false 时,该属性被称为“不可写的”。它不能被重新赋值。

var o = {}; // 创建一个新对象Object.defineProperty(o, 'a', {value: 37,writable: false
});console.log(o.a); //  37
o.a = 25; // No error thrown  不会抛出错误,但是也更改不了这个值,因为这个不是在严格模式下
// (it would throw in strict mode,
// even if the value had been the same)
console.log(o.a); // 还是37 // strict mode
(function() {'use strict';var o = {};Object.defineProperty(o, 'b', {value: 2,writable: false});o.b = 3; // throws TypeError: "b" is read-onlyreturn o.b; // returns 2 without the line above
}());
  •  value :  默认undefined

如果对象中不存在指定的属性,Object.defineProperty() 会创建这个属性。当描述符中省略某些字段时,这些字段将使用它们的默认值。

var o = {}; // 创建一个新对象// 在对象中添加一个属性与数据描述符的示例
Object.defineProperty(o, "a", {value : 37,writable : true,enumerable : true,configurable : true
});// 对象 o 拥有了属性 a,值为 37// 在对象中添加一个设置了存取描述符属性的示例
var bValue;
Object.defineProperty(o, "b", {// 使用了方法名称缩写(ES2015 特性)// 下面两个缩写等价于:// get : function() { return bValue; },// set : function(newValue) { bValue = newValue; },get() { return bValue; },set(newValue) { bValue = newValue; },enumerable : true,configurable : true
});o.b; // 38
// 对象 o 拥有了属性 b,值为 38
// 现在,除非重新定义 o.b,o.b 的值总是与 bValue 相同// 数据描述符和存取描述符不能混合使用
Object.defineProperty(o, "conflict", {value: 0x9f91102,get() { return 0xdeadbeef; }
});
// 抛出错误 TypeError: value appears only in data descriptors, get appears only in accessor descriptors
  • get: 当我们通过person.name访问name的值时,get将被调用。该方法可以自定义返回的具体值是多少。get默认值为undefined
  • set: 当我们通过person.name = 'Jake'设置name的值时,set方法将被调用。该方法可以自定义设置值的具体方式。set默认值为undefined

考虑特性被赋予的默认特性值非常重要,通常,使用点运算符和 Object.defineProperty() 为对象的属性赋值时,数据描述符中的属性默认值是不同的

var o = {};o.a = 1;
// 默认做了下边这件事,等同于:
Object.defineProperty(o, "a", {value: 1,writable: true,configurable: true,enumerable: true
});// 如果这样定义,
Object.defineProperty(o, "a", { value : 1 });
// 默认做了下边这件事,等同于:
Object.defineProperty(o, "a", {value: 1,writable: false,configurable: false,enumerable: false
});

需要注意的是,不能同时设置value、writable 与 get、set的值。

var person = {}// 通过get与set自定义访问与设置name属性的方式
Object.defineProperty(person, 'name', {get: function() {// 一直返回TOMreturn 'TOM'},set: function(value) {// 设置name属性时,返回该字符串,value为新值console.log(value + ' in set');}
})// 第一次访问name,调用get
console.log(person.name)   // TOM// 尝试修改name值,此时set方法被调用
person.name = 'alex'   // alex in set// 第二次访问name,还是调用get
console.log(person.name) // TOM

请尽量同时设置get、set。如果仅仅只设置了get,那么我们将无法设置该属性值。如果仅仅只设置了set,我们也无法读取该属性的值。

2.Object.defineProperties

当我们想要同时设置多个属性的特性时,需要使用Object.defineProperties

语法:  Object.defineProperties(obj, props)

参数说明

obj

在其上定义或修改属性的对象。

props

要定义其可枚举属性或修改的属性描述符的对象。对象中存在的属性描述符主要有两种:数据描述符和访问器描述符(更多详情,请参阅Object.defineProperty())。描述符具有以下键:

configurable

true 当且仅当该属性描述符的类型可以被改变并且该属性可以从对应对象中删除。
默认为 false

enumerable

true 当且仅当在枚举相应对象上的属性时该属性显现。
默认为 false

value

与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。
默认为 undefined.

writable

true当且仅当与该属性相关联的值可以用assignment operator改变时。
默认为 false

get

作为该属性的 getter 函数,如果没有 getter 则为undefined。函数返回值将被用作属性的值。
默认为 undefined

set

作为属性的 setter 函数,如果没有 setter 则为undefined。函数将仅接受参数赋值给该属性的新值。
默认为 undefined

用法除了格式基本与Object.defineProperty相同

var person = {}Object.defineProperties(person, {name: {value: 'Jake',configurable: true},age: {get: function() {return this.value || 22},set: function(value) {this.value = value}}
})person.name   // Jake
person.age    // 22

读取属性的特性值

我们可以使用Object.getOwnPropertyDescriptor方法读取某一个属性的特性值。

var person = {}Object.defineProperty(person, 'name', {value: 'alex',writable: false,configurable: false
})var descripter = Object.getOwnPropertyDescriptor(person, 'name');console.log(descripter);  // 返回结果如下descripter = {configurable: false,enumerable: false,value: 'alex',writable: false
}

js之Object.defineProperty和Object.defineProperties详解相关推荐

  1. Object.defineProperty()方法的用法详解

    Object.defineProperty()函数是给对象设置属性的. Object.defineProperty(object, propertyname, descriptor); 一共有三个参数 ...

  2. Incremental Learning of Object Detectors without Catastrophic Forgetting详解

    Incremental Learning of Object Detectors without Catastrophic Forgetting详解 最近由于项目的需要在研究incremental l ...

  3. Object.keys()的详解和用法

    Object.keys()的详解和用法 在实际开发中,我们有时需要知道对象的所有属性; ES5 引入了Object.keys方法,成员是参数对象自身的(不含继承的)所有可遍历( enumerable ...

  4. vue.js循环for(列表渲染)详解

    vue.js循环for(列表渲染)详解 一.总结 一句话总结: v-for <ul id="example-1"> <li v-for="item in ...

  5. 基于PHP和JS的AES相互加密解密方法详解(CryptoJS)

    在最近的项目中,前端后台数据交互需要进行加密之后传输使用,以保证系统数据的安全.有关数据加密解密的问题,有很多种加密的方式,在这里我选择了AES的加密方式.特此写下此篇博文,总结讲述下PHP和JS进行 ...

  6. js keyup、keypress和keydown事件 详解

    js keyup.keypress和keydown事件  详解 js keyup.keypress和keydown事件都是有关于键盘的事件 当一个按键被pressed 或released在每一个现代浏 ...

  7. Vue.js - Font Awesome字体图标的使用详解(vue-fontawesome库)

    Vue.js - Font Awesome字体图标的使用详解(vue-fontawesome库) Font Awesome 是一个十分优秀的第三方图标库,我之前也写过文章介绍如何在 html 页面中使 ...

  8. JS - 文件上传组件WebUploader使用详解1(带进度的文件上传

    一.基本介绍 1,什么是 WebUploader? WebUploader 是由百度公司团队开发的一个以 HTML5 为主,FLASH 为辅的现代文件上传组件. 官网地址:http://fex.bai ...

  9. js中childNodes易错点、详解定义以及用法

    js中childNodes易错点.详解定义以及用法 最近学习的时候,我遇到了childNodes的一些问题,我查阅了一些资料,总结一下其定义及用法.在学习childNodes之前,我们需要先了解一下D ...

  10. aes js加密php解密实例,基于PHP和JS的AES相互加密解密方法详解(CryptoJS)_PHP_JS_AES源码...

    [实例简介] 基于PHP和JS的AES相互加密解密方法详解(CryptoJS)_PHP_JS_AES源码 [实例截图] [核心代码] 基于PHP和JS的AES相互加密解密方法详解(CryptoJS)_ ...

最新文章

  1. I am the load of my word
  2. Freebsd下如何安装配置ssh
  3. 多除了1次100的FM BAPI_CURRENCY_CONV_TO_INTERN_9
  4. 数据结构之串:基本概念
  5. 配置syslog发送_Citrix ADC Syslog配置推荐
  6. 微课|中学生可以这样学Python(例3.1):闰年判断
  7. graphpad多条不同的曲线_应用Graphpad Prism制作多组ROC曲线图
  8. 技巧 | Markdown 语法中首行缩进的方法
  9. java 换行规范_JAVA代码规范(一)
  10. Datawhale打卡活动 Kaggle Spaceship Titanic Day3
  11. ECMAScript(pink)
  12. windows 启动后台进程
  13. 怎么微信WeixinJSBridge.invoke支付成功居然不跳转?还把我页面给关了!这篇文章就告诉你What should I do!
  14. HFSS保姆级学习笔记实践篇(一)矩形微带贴片天线初步设计
  15. nginx代理tcp服务
  16. 2020年广东工业大学第十届文远知行杯新生程序设计竞赛 A.肥猪的钢琴床(dp动态规划)
  17. 知乎 mysql in 与 join_join和join in之间有什么区别?
  18. java json 序列化对象空值不处理_jackson 实体转json 为NULL或者为空不参加序列化(实例讲解)...
  19. KVM虚拟化解决方案系列之KVM架构篇
  20. [转]QQ经典签名100句 - [绝对经典]

热门文章

  1. C# invoke 和 begininvoke 用法
  2. 模型计算机微指令总表,计算机组成和结构微指令表(总).doc
  3. windows xp sp3序列号
  4. visionPro8.2r紧急许可重复利用方法
  5. 【Python知识点梳理】10.Python的垃圾回收机制、代码规范及命令行参数
  6. 《空》孙溟㠭篆刻艺术
  7. 有趣的微分方程之欧拉方程
  8. miRNA数据库篇——miRWalk:综合型的miRNA靶基因数据库
  9. SQL从杂乱的字符串字段中统计数字部份的最大值
  10. Python每日一练(20230307) 重复DNA序列、搜索二维矩阵、买卖股票的最佳时机IV