(译)ECMAScript 5 Objects and Properties (一)
@by: Aaron
有一些新的API包含在规范中,但是更多有趣的功能发挥作用是 对象/属性 代码,如何使用能作用你的对象,通过私有的"getters" 和 "settses",阻止枚举,操作,或者删除,甚至防止添加新属性.简而言之:你将能够复制和扩展现有的基于JavaScript的api(如DOM)只使用JavaScript本身。
也许最重要的是,尽管:这些特性将到达在所有主要的浏览器。所有主要的浏览器厂商从事规范并同意实施在他们各自的引擎。但是确切的时间表还不清楚,但这将是早,而非更晚。
ES5在这一点上似乎还没有存在的完整实现,但是有一些作品。在此期间你可以阅读ECMAScript 5规范
Objects
一个ECMAScript 5新特点是扩展性对象能够被切换。关闭可扩展性可以防止新的属性添加到一个对象上
Object.preventExtensions( obj )
Object.isExtensible( obj )
preventExtensions锁定了一个对象,阻止和将来的属性发生冲突
isExtensible是一个方法来确定当前对象的可扩展性。
示例用法:
var obj = {}; obj.name = "John"; print( obj.name ); // John print( Object.isExtensible( obj ) ); // true Object.preventExtensions( obj ); obj.url = "http://ejohn.org/"; // Exception in strict mode print( Object.isExtensible( obj ) ); // false
属性和描述符:
属性已经被彻底颠覆。不再是简单的值关联的对象——你现在拥有完全控制如何表现。用这能力,虽然,是增加了复杂性。
对象属性分为两个部分.
对于实际的“meat”的一个属性有两种可能性:一个值(,我们ECMAScript 3知道,一个“数据”属性—这是传统的值)或一个Getter和Setter(从一些现代浏览器我们知道,一个“访问”属性,就像Gecko和WebKit)。
- Value 包含该属性的值.
- Get 函数调用时该属性的值被访问。
- Set 调用函数,该属性的值是变化的。
另外,属性可以被…
- Writable. 假如是false,这个属性的值不能被改变.
- Configurable. 假如是flase,任何试图去删除这个属性或者改变它的特性(Writable, Configurable, or Enumerable)都将失败.
- Enumerable. 假如是true,当用for (var prop in obj){}(用着其他相似功能),这个属性可以被遍历出来
这些不同的属性完全弥补属性描述符。例如,一个简单的描述符可能类似于以下:
{ value: "test", writable: true, enumerable: true, configurable: true }
这三个属性(writable, enumerable, and configurable)都是可选的,所有默认为true
你能够用new Object.getOwnPropertyDescriptor 的方法得到它的信息
Object.getOwnPropertyDescriptor( obj, prop )
这种方法允许您访问描述符的属性。这个方法是唯一的方式来获得这些信息(否则,不提供给用户——这些不存在可见的属性的属性,它们存储在内部的ECMAScript引擎)。
示例使用:
var obj = { foo: "test" }; print(JSON.stringify( Object.getOwnPropertyDescriptor( obj, "foo" ) )); // {"value": "test", "writable": true, // "enumerable": true, "configurable": true}
Object.defineProperty( obj, prop, desc )
这个方法允许你在一个对象上(或者改变这个存在的属性)定义个新的属性.这个方法接受一个属性描述符用来初始化(更新)属性
示例使用:
var obj = {}; Object.defineProperty( obj, "value", { value: true, writable: false, enumerable: true, configurable: true }); (function(){ var name = "John"; Object.defineProperty( obj, "name", { get: function(){ return name; }, set: function(value){ name = value; } }); })(); print( obj.value ) // true print( obj.name ); // John obj.name = "Ted"; print( obj.name ); // Ted for ( var prop in obj ) { print( prop ); } // value // name obj.value = false; // Exception if in strict mode Object.defineProperty( obj, "value", { writable: true, configurable: false }); obj.value = false; print( obj.value ); // false delete obj.value; // Exception
Object.defineProperty 在新的ECMAScript版本中是一个核心的方法.几乎所有其他主要功能的的实现都依赖这个方法上
Object.defineProperties( obj, props )
意思是同时定义个一些属性(而不是单独的一个)
Object.defineProperties = function( obj, props ) { for ( var prop in props ) { Object.defineProperty( obj, prop, props[prop] ); } };
var obj = {}; Object.defineProperties(obj, { "value": { value: true, writable: false }, "name": { value: "John", writable: false } });
在ECMAScript5的新功能中,属性描述符(及其相关方法)可能是最重要的.它使开发人员能够有细粒度的控制他们的对象,防止不受欢迎的修修补补,和维护一个统一的网络兼容的API。