javascript技巧

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript技巧 > JavaScript属性描述对象

你必须了解的JavaScript中的属性描述对象详解(上)

作者:程序小猿2

JavaScript提供了一个内部数据结构,用来描述对象的属性,控制它的行为,比如该属性是否可写、可遍历等等。这个内部数据结构称为“属性描述对象”。本文主要带大家了解一下JavaScript中你必须了解的属性描述对象,需要的可以参考一下

属性描述对象

JavaScript其实支持多种编程范式的,包括函数式编程和面向对象编程:

所以,属性描述对象的概念就为:JavaScript提供了一个内部数据结构,用来描述对象的属性,控制它的行为,比如该属性是否可写、可遍历等等。这个内部数据结构称为“属性描述对象”(attributes object)。每个属性都有自己对应的属性描述对象,保存该属性的一些元信息。

下面是属性描述对象的一个例子。

{
    value:123,
    writable:false,
    enumerable:true,
    configurable:false,
    get:undefined,
    set:undefined
}    

属性描述对象提供六个元属性。

Object.getOwnPropertyDescriptor()

Object.getOwnPropertyDescriptor()方法可以获取属性描述对象。他的第一个参数是目标对象,第二个参数是一个字符串,对应目标对象的某个属性名。

var obj = (p:'a'};

Object.getOwnPropertyDescriptor(obj,'p')
//Object{ value:"a",
//       writable:true,
//       enumerable:true,
//       configurable:true
  }        

上面代码中,Object.getOwnPropertyDescriptor()方法获取obj.p的属性描述对象。

注意,Object.getOwnPropertyDescriptor()方法只能用于对象自身的属性,不能用于继承的属性。

var obj = {p:'a');

Object.getOwnPropertyDescriptor(obj,'toStrng')
//undefined

上面代码中,toStringobj对象继承的属性,Object.getOwnPropertyDescriptor()无法获取。

Object.getOwnPropertyNames()

Object.getOwnPropertyNames方法返回一个数组,成员是参数对象自身的全部属性的属性名,不管该属性是否可遍历。

var obj = Object.defineProperties({},{
    p1:{value:1,enumerable:true},
    p2:{value:2,enumerable:false}
});

Object.getOwnPropertyNames(obj)
//["p1","p2"]

上面代码中,obj.p1是可遍历的,obj.p2是不可遍历的。Object.getOwnPropertyNames会将它们都返回。

这跟Object.keys的行为不同,Object.keys只返回对象自身的可遍历属性的全部属性名。

Object.keys([])//[]
Object.getOwnPropertyNmaes([])//['length']

Object.keys(Object.prototype)// []
Object.getOwnPropertyNames(Object.prototype)
//['hasOwmProperty'
//   'valueOf',
//   'constructor',
//   'toLocaleString',
//   'isPrototypeOf',
//   'propertyIsEnumerable',
//   'toString']

上面代码中,数组自身的length属性是不可遍历的,Object.keys不会返回该属性。第二个例子Object.prototype也是一个对象,所有实例对象都会继承它,它自身的属性都是不可遍历的。

Object.defineProperty(),Object.defineProperties()

Object.defineProperty()方法允许通过属性描述对象,定义或修改一个属性,然后返回修改后的对象,它的用法如下。

Object.defineProperty(object,propertyName,attributesObject)

Object.defineProperty方法接受三个参数,依次如下。

举例来说,定义obj.p可以写成下面这样。

var obj = Object.defineProperty({},'p',{
    value:123,
    writable:false,
    enumerable:true,
    configurable:false
});

obj.p //123

obj.p = 246;
obj.p //123

上面代码中,Object.defineProperty()方法定义了obj.p属性。由于属性描述对象的writable属性为false,所以obj.p属性不可写。注意,这里的Object.defineProperty方法的第一个参数是{}(一个新建的空对象),p属性直接定义在这个空对象上面,然后返回这个对象,这是Object.defineProperty()的常见用法。

如果属性已经存在,Object.defineProperty()方法相当于更新该属性的属性描述对象。

如果一次性定义或修改多个属性,可以使用Object.defineProperties()方法。

var obj = Object.defineProperties({},{
    p1:{value:123,enumerable:true},
    p2:{value:'abc',enumerable:true},
    p3:{get:function(){return this.p1 + this.p2},
       enumerable:true,
       configurable:true
      }
  });
  
  obj.p1 //123
  obj.p2 //"abc"
  obj.p3 //"123abc"

上面代码中,Object.defineProperties()同时定义了obj对象的三个属性。其中,p3属性定义了取值函数get,即每次读取该属性,都会调用这个取值函数。

注意,一旦定义了取值函数get(或存值函数set),就不能将writable属性设为true,或者同时定义value属性,否则会报错。

var obj = {};

Object.defineProperty(obj,'p',{
    value:123,
    get:function(){return 456;}
});
//TypeError: Invalid property.
// A property cannot both have accessors and be writable or have a value

Object.defineProperty(obj,'p'{
    writable:true,
    get:function(){return 456;}
});
// TypeError: Invalid property descriptor.
// Cannot both specify accessors and a value or writable attribute

上面代码中,同时定义了get属性和value属性,以及将writable属性设为true,就会报错。

Object.defineProperty()Object.defineProperties()参数里面的属性描述对象,writableconfigurableenumerable这三个属性的默认值都为false

var obj = {};
Object.defineProperty(obj,'foo',{});
Object.getOwnPropertyDescriptor(obj,'foo')
//{
//    value:undefined,
//    writable:false,
//    enumerable:false,
//    configurable:false
//}

上面代码中,定义obj.foo时用了一个空的属性描述对象,就可以看到各个元属性的默认值。

Object.prototype.propertyIsEnumerable()

实例对象的propertyIsEnumerable()方法返回一个布尔值,用来判断某个属性是否可遍历。注意,这个方法只能用于判断对象自身的属性,对于继承的属性一律返回false

var obj = {};
obj.p = 123;

obj.propertyIsEnumerable('p') //true
obj.propertyIsEnumerable('toString') //false

上面代码中,obj.p是可遍历的,而obj.toString是继承的属性。

到此这篇关于你必须了解的JavaScript中的属性描述对象详解(上)的文章就介绍到这了,更多相关JavaScript属性描述对象内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文