Object.definedProperty

该方法允许精确添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,能够在属性枚举期间呈现出来(for...in 或 Object.keys 方法), 这些属性的值可以被改变,也可以被删除。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改的。

语法

  1. Object.defineProperty(obj, prop, descriptor)
  2. 参数
  3. obj
  4. 要在其上定义属性的对象。
  5. prop
  6. 要定义或修改的属性的名称。
  7. descriptor
  8. 将被定义或修改的属性描述符。
  9. 返回值
  10. 被传递给函数的对象。

属性描述符

  1. 对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。存取描述符是由getter-setter函数对描述的属性。描述符必须是这两种形式之一;不能同时是两者。
  2. 数据描述符和存取描述符均具有以下可选键值:
  3. configurable
  4. 当且仅当该属性的 configurable true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为 false
  5. enumerable
  6. 当且仅当该属性的enumerabletrue时,该属性才能够出现在对象的枚举属性中。默认为 false
  7. 数据描述符同时具有以下可选键值:
  8. value
  9. 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。默认为 undefined
  10. writable
  11. 当且仅当该属性的writabletrue时,value才能被赋值运算符改变。默认为 false
  12. 存取描述符同时具有以下可选键值:
  13. get
  14. 一个给属性提供 getter 的方法,如果没有 getter 则为 undefined。当访问该属性时,该方法会被执行,方法执行时没有参数传入,但是会传入this对象(由于继承关系,这里的this并不一定是定义该属性的对象)。
  15. 默认为 undefined
  16. set
  17. 一个给属性提供 setter 的方法,如果没有 setter 则为 undefined。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。
  18. 默认为 undefined
  1. 如果一个描述符不具有value,writable,get set 任意一个关键字,那么它将被认为是一个数据描述符。如果一个描述符同时有(valuewritable)和(getset)关键字,将会产生一个异常。
  2. 记住,这些选项不一定是自身属性,如果是继承来的也要考虑。为了确认保留这些默认值,你可能要在这之前冻结 Object.prototype,明确指定所有的选项,或者通过 Object.create(null)将__proto__属性指向null
  3. // 使用 __proto__
  4. var obj = {};
  5. var descriptor = Object.create(null); // 没有继承的属性
  6. // 默认没有 enumerable,没有 configurable,没有 writable,隐式配置
  7. descriptor.value = 'static';
  8. Object.defineProperty(obj, 'key', descriptor);
  9. // 显式配置
  10. Object.defineProperty(obj, "key", {
  11. enumerable: false,
  12. configurable: false,
  13. writable: false,
  14. value: "static"
  15. });

描述符具有的键值

描述符 configurable enumerable value writable get set
数据描述符 Yes Yes Yes Yes No No
存取描述符 Yes Yes No No Yes Yes
  1. var o = {}; // 创建一个新对象
  2. // 在对象中添加一个属性与数据描述符的示例
  3. Object.defineProperty(o, "a", {
  4. value : 37,
  5. writable : true,
  6. enumerable : true,
  7. configurable : true
  8. });
  9. // 对象o拥有了属性a,值为37
  10. // 在对象中添加一个属性与存取描述符的示例
  11. var bValue;
  12. Object.defineProperty(o, "b", {
  13. get : function(){
  14. return bValue;
  15. },
  16. set : function(newValue){
  17. bValue = newValue;
  18. },
  19. enumerable : true,
  20. configurable : true
  21. });
  22. o.b = 38;
  23. // 对象o拥有了属性b,值为38
  24. // o.b的值现在总是与bValue相同,除非重新定义o.b
  25. // 数据描述符和存取描述符不能混合使用
  26. Object.defineProperty(o, "conflict", {
  27. value: 0x9f91102,
  28. get: function() {
  29. return 0xdeadbeef;
  30. }
  31. });
  32. // throws a TypeError: value appears only in data descriptors, get appears only in accessor descriptors

修改属性

Writable 属性

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


  1. var o = {}; // Creates a new object
  2. Object.defineProperty(o, 'a', {
  3. value: 37,
  4. writable: false
  5. });
  6. console.log(o.a); // logs 37
  7. o.a = 25; // No error thrown

Enumerable属性

  1. var o = {};
  2. Object.defineProperty(o, "a", { value : 1, enumerable:true });
  3. Object.defineProperty(o, "b", { value : 2, enumerable:false });
  4. Object.defineProperty(o, "c", { value : 3 }); // enumerable defaults to false
  5. o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则这个属性的enumerable为true
  6. Object.keys(o); // ["a", "d"]
  7. o.propertyIsEnumerable('a'); // true
  8. o.propertyIsEnumerable('b'); // false
  9. o.propertyIsEnumerable('c'); // false

configurable属性

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


  1. var o = {};
  2. Object.defineProperty(o, "a", { get : function(){return 1;},
  3. configurable : false } );
  4. // throws a TypeError
  5. Object.defineProperty(o, "a", {configurable : true});
  6. // throws a TypeError
  7. Object.defineProperty(o, "a", {enumerable : true});
  8. // throws a TypeError (set was undefined previously)
  9. Object.defineProperty(o, "a", {set : function(){}});
  10. // throws a TypeError (even though the new get does exactly the same thing)
  11. Object.defineProperty(o, "a", {get : function(){return 1;}});
  12. // throws a TypeError
  13. Object.defineProperty(o, "a", {value : 12});
  14. console.log(o.a); // logs 1
  15. delete o.a; // Nothing happens
  16. console.log(o.a); // logs 1
  17. //如果o.a的configurable属性为true,则不会抛出任何错误,并且该属性将在最后被删除。

添加多个属性值和默认值

  1. var o = {};
  2. o.a = 1;
  3. // 等同于 :
  4. Object.defineProperty(o, "a", {
  5. value : 1,
  6. writable : true,
  7. configurable : true,
  8. enumerable : true
  9. });
  10. // 另一方面,
  11. Object.defineProperty(o, "a", { value : 1 });
  12. // 等同于 :
  13. Object.defineProperty(o, "a", {
  14. value : 1,
  15. writable : false,
  16. configurable : false,
  17. enumerable : false
  18. });

setter和getter


  1. function Archiver() {
  2. var temperature = null;
  3. var archive = [];
  4. Object.defineProperty(this, 'temperature', {
  5. get: function() {
  6. console.log('get!');
  7. return temperature;
  8. },
  9. set: function(value) {
  10. temperature = value;
  11. archive.push({ val: temperature });
  12. }
  13. });
  14. this.getArchive = function() { return archive; };
  15. }
  16. var arc = new Archiver();
  17. arc.temperature; // 'get!'
  18. arc.temperature = 11;
  19. arc.temperature = 13;
  20. arc.getArchive(); // [{ val: 11 }, { val: 13 }]
  21. //or
  22. var pattern = {
  23. get: function () {
  24. return 'I alway return this string,whatever you have assigned';
  25. },
  26. set: function () {
  27. this.myname = 'this is my name string';
  28. }
  29. };
  30. function TestDefineSetAndGet() {
  31. Object.defineProperty(this, 'myproperty', pattern);
  32. }
  33. var instance = new TestDefineSetAndGet();
  34. instance.myproperty = 'test';
  35. // 'I alway return this string,whatever you have assigned'
  36. console.log(instance.myproperty);
  37. // 'this is my name string'
  38. console.log(instance.myname);继承属性

继承属性

如果访问者的属性是被继承的,它的 get 和set 方法会在子对象的属性被访问或者修改时被调用。如果这些方法用一个变量存值,该值会被所有对象共享。

  1. function myclass() {
  2. }
  3. var value;
  4. Object.defineProperty(myclass.prototype, "x", {
  5. get() {
  6. return value;
  7. },
  8. set(x) {
  9. value = x;
  10. }
  11. });
  12. var a = new myclass();
  13. var b = new myclass();
  14. a.x = 1;
  15. console.log(b.x); // 1
  16. 这可以通过将值存储在另一个属性中固定。在 get set 方法中,this 指向某个被访问和修改属性的对象。
  17. function myclass() {
  18. }
  19. Object.defineProperty(myclass.prototype, "x", {
  20. get() {
  21. return this.stored_x;
  22. },
  23. set(x) {
  24. this.stored_x = x;
  25. }
  26. });
  27. var a = new myclass();
  28. var b = new myclass();
  29. a.x = 1;
  30. console.log(b.x); // undefined
  31. 不像访问者属性,值属性始终在对象自身上设置,而不是一个原型。然而,如果一个不可写的属性被继承,它仍然可以防止修改对象的属性。
  1. function myclass() {
  2. }
  3. myclass.prototype.x = 1;
  4. Object.defineProperty(myclass.prototype, "y", {
  5. writable: false,
  6. value: 1
  7. });
  8. var a = new myclass();
  9. a.x = 2;
  10. console.log(a.x); // 2
  11. console.log(myclass.prototype.x); // 1
  12. a.y = 2; // Ignored, throws in strict mode
  13. console.log(a.y); // 1
  14. console.log(myclass.prototype.y); // 1

Object.defineProperty使用技巧的更多相关文章

  1. javascript之Object.defineProperty的奥妙

    直切主题 今天遇到一个这样的功能: 写一个函数,该函数传递两个参数,第一个参数为返回对象的总数据量,第二个参数为初始化对象的数据.如: var o = obj (4, {name: 'xu', age ...

  2. Object.defineproperty实现数据和视图的联动

    Object.defineproperty语法 var o = {}; // 创建一个新对象 // Example of an object property added with definePro ...

  3. Vue 双向数据绑定原理分析 以及 Object.defineproperty语法

    第三方精简版实现 https://github.com/luobotang/simply-vue Object.defineProperty 学习,打开控制台分别输入以下内容调试结果 userInfo ...

  4. Object.defineProperty vs __defineGetter__ vs normal

    Testing in Chrome 31.0.1650.63 32-bit on Windows Server 2008 R2 / 7 64-bit Test Ops/sec Object.defin ...

  5. Object.defineProperty

    属性类型ECMA-262第5版在定义只有内部才用的特性(attribute)时,描述了属性(property)的各种特征.ECMA-262定义这些特性是为了实现JavaScript引擎用的,因此在Ja ...

  6. Object.defineproperty实现数据和视图的联动 ------是不是就是 Angular 模型和视图的同步的实现方式???

    参考:http://www.cnblogs.com/oceanxing/p/3938443.html https://developer.mozilla.org/zh-CN/docs/Web/Java ...

  7. 20+行代码使用es5 Object.defineProperty 实现简单的watch功能

    /** * 一个简单的demo 帮助理解defineProperty,只对Object类型参数有效 */ $watch=function(myObject,callback){ function in ...

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

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

  9. 理解Object.defineProperty()

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

随机推荐

  1. Python 中的 10 个常见安全漏洞,以及如何避免(下)

    简评:编写安全代码很困难,当你学习一个编程语言.模块或框架时,你会学习其使用方法. 在考虑安全性时,你需要考虑如何避免被滥用,Python 也不例外,即使在标准库中,也存在用于编写应用的不良实践.然而 ...

  2. javascript 私有化属性,和公共属性

    function TestClassA(name, number) { this.name = name; //public this.number = number; //public var ac ...

  3. luogu4074 [WC2013]糖果公园(树上带修莫队)

    link 题目大意:给一个树,树上每个点都有一种颜色,每个颜色都有一个收益 每次修改一个点上的颜色 或询问一条链上所有颜色第i次遇到颜色j可以获得w[i]*v[j]的价值,求链上价值和 题解:树上带修 ...

  4. jquery实现简易的计算器

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. SQL语句之数据库操作

    SQL语句系列 1.SQL语句之行操作 2.SQL语句之表操作 3.SQL语句之数据库操作 4.SQL语句之用户管理 占坑,带写……

  6. Stack — 20181121

    12. Min Stack public class MinStack { Stack<Integer> stack; Stack<Integer> minStack; pub ...

  7. java-web 登陆功能

    目录结构 web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi= ...

  8. spring的总结

    1. 第一天 问题:怎样的程序是一个优秀的程序 可维护性好,可扩展性好,性能优秀 问题:业界对象提供什么的概念 高内聚,低耦合,也就是尽量使代码对应的功能写在对应的模块,并且尽量减少类与类之间的关系, ...

  9. 转 JSON在PHP中的基本应用

    PHP原生提供json_encode()和json_decode()函数,前者用于编码,后者用于解码. 一.json_encode() 该函数主要用来将数组和对象,转换为json格式.先看一个数组转换 ...

  10. Android可见APP的不可见任务栈(TaskRecord)销毁分析

    Android依托Java型虚拟机,OOM是经常遇到的问题,那么在快达到OOM的时候,系统难道不能回收部分界面来达到缩减开支的目的码?在系统内存不足的情况下,可以通过AMS及LowMemoryKill ...