UNDERSTANDING OBJECTS——了解对象
早期的开发者这样定义对象:
var person = new Object();
person.name = “Nicholas”;
person.age = 29;
后来人们倾向于:
var person = {
name: “Nicholas”,
age: 29,
job: “Software Engineer”,
sayName: function(){
alert(this.name);
}
};
Types of Properties——属性类型
ECMA-262 fi fth edition describes characteristics of properties through the use of internal-only
attributes. These attributes are defi ned by the specifi cation for implementation in JavaScript engines,
and as such, these attributes are not directly accessible in JavaScript. To indicate that an attribute is
internal, surround the attribute name with two pairs of square brackets, such as [[Enumerable]].
Although ECMA-262 third edition had different defi nitions, this book refers only to the fi fth
edition descriptions.
There are two types of properties: data properties and accessor properties.
总得来说有两种:data properties and accessor properties.
Data Properties
Data properties contain a single location for a data value.Data properties have four attributes describing their behavior
[[Configurable]]、[[Enumerable]] 、[[Writable]] 、[[Value]]
用以下对象作为例子:
var person = {
name: “Nicholas”
};
[[Configurable]]只能设置一次,再次设置出错。
var person = {};
Object.defineProperty(person, “name”, {
configurable: false,
value: “Nicholas”
});
alert(person.name); //”Nicholas”
delete person.name;
alert(person.name); //”Nicholas”
[[Writable]] 是否可写
var person = {};
Object.defineProperty(person, “name”, {
writable: false,
value: “Nicholas”
});
alert(person.name); //”Nicholas”
person.name = “Greg”;
alert(person.name); //”Nicholas”
[[Value]] 更改值
无说明
Accessor Properties
Accessor properties do not contain a data value. Instead, they contain a combination of a getter
function and a setter function (though both are not necessary).
[[Configurable]]、[[Enumerable]] 、[[Get]]、[[Set]]
var book = {
_year: 2004,
edition: 1
};
Object.defineProperty(book, “year”, {
get: function(){
return this._year;
},
set: function(newValue){
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
});
book.year = 2005;
alert(book.edition); //2
In this code, an object book is created with two default properties: _year and edition. The
underscore on _year is a common notation to indicate that a property is not intended to be accessed
from outside of the object’s methods. The year property is defi ned to be an accessor property
where the getter function simply returns the value of _year and the setter does some calculation
to determine the correct edition. So changing the year property to 2005 results in both _year and
edition changing to 2. This is a typical use case for accessor properties, when setting a property
value results in some other changes to occur.
It’s not necessary to assign both a getter and a setter. Assigning just a getter means that the property
cannot be written to and attempts to do so will be ignored. In strict mode, trying to write to a
property with only a getter throws an error. Likewise, a property with only a setter cannot be read and
will return the value undefined in nonstrict mode, while doing so throws an error in strict mode.
Prior to the ECMAScript 5 method, which is available in Internet Explorer 9+ (Internet Explorer 8
had a partial implementation), Firefox 4+, Safari 5+, Opera 12+, and Chrome, two nonstandard
methods were used to create accessor properties: __defineGetter__() and __defineSetter__().
These were fi rst developed by Firefox and later copied by Safari 3, Chrome 1, and Opera 9.5. The
previous example can be rewritten using these legacy methods as follows:
var book = {
_year: 2004,
edition: 1
};
//legacy accessor support
book.__defi neGetter__(“year”, function(){
return this._year;
});
book.__defi neSetter__(“year”, function(newValue){
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
});
book.year = 2005;
alert(book.edition); //2
There is no way to modify [[Configurable]] or [[Enumerable]] in browsers that don’t support
Object.defineProperty().
来源JS高级编程3版