- 一、Object 的创建方法
- 二、读写对象属性
- 三、对象实例属性和方法
- 四、属性类型
- 五、定义单个属性:Object.defineProperty()
- 六、 定义多个属性:Object.defineProperties()
- 七、读取属性的特性 Object.getOwnPropertyDescriptor()
- 八、Object.create()
其他链接:
以下内容全部源于: 《JavaScript高级程序设计(第3版)》
一、Object 的创建方法
1.1 new操作符
var obj1 = new Object();
// 括号可以省略,但不推荐
var obj2 = new Object;
1.2 对象字面量表示法
var obj = {};
二、读写对象属性
var person = {
'age': 19
};
// 对象属性的读取
// 第一种:方括号
console.log(person['age']);
// 第二种:点表示
console.log(person.age);
// 对象属性的设置
// 第一种:方括号
person['age'] = 20;
// 第二种:点表示
person.age = 20;
如果属性名中包含会导致语法错误的字符,或者属性名使用的是关键字或保留字,也可以使用方括 号表示法。
person["first name"] = "Nicholas";
三、对象实例属性和方法
Object
的每个实例都具有下列属性。
- 1.
constructor
:- 保存用于创建当前对象的函数。
var person = new Object();
console.log(person.constructor); // function Object(){}
Object
的每个实例都具有下列方法。(propertyName
参数须以字符串形式指定。)
- 1.
hasOwnProperty(propertyName)
:- 用于检查给定的属性是否在当前对象实例中(不是在实例的原型中)。
var person = {
name: 'baby',
sex: 'girl'
};
console.log(person.hasOwnProperty('sex')); // true
- 2.
isPrototypeOf(Object)
:- 检查传入的对象是否是传入对象的原型
- 3.
propertyIsEnumerable(propertyName)
:- 检查给定的属性是否能用
for-in
枚举。
- 检查给定的属性是否能用
- 4.
toLocaleString()
:- 返回对象的字符串表示,该字符串与执行环境的地区对应
- 5.
toString()
:- 返回对象的字符串表示
- 6.
valueOf
:- 返回对象的字符串、数值、布尔值表示。通常与
toString()
方法的返回值相同。
- 返回对象的字符串、数值、布尔值表示。通常与
四、属性类型
ECMAScript
中有两种属性:数据属性和访问器属性。
4.1 数据属性
数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有 4 个描述其行为的特性。
- 1.
[[Configurable]]
:- 表示能否通过
delete
删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。 - 默认值:
true
- 表示能否通过
- 2.
[[Enumerable]]
:- 表示能否通过
for-in
循环返回属性。 - 默认值:
true
- 表示能否通过
- 3.
[[Writable]]
:- 表示能否修改属性的值。
- 默认值:
true
- 4.
[[Value]]
:- 包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。
- 默认值:
undefined
var person = {
name: "Nicholas"
};
// [[Configurable]]、[[Enumerable]]、[[Writable]]特性都被设置为 true,
// 而[[Value]]特性被设置为指定的值:Nicholas
4.2 访问器属性
- 1.
[[Configurable]]
:- 表示能否通过
delete
删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。 - 默认值:
true
- 表示能否通过
- 2.
[[Enumerable]]
:- 表示能否通过
for-in
循环返回属性。 - 默认值:
true
- 表示能否通过
- 3.
[[Get]]
:- 在读取属性时调用的函数。
- 默认值:
undefined
- 4.
[[Set]]
:- 在写入属性时调用的函数。
- 默认值:
undefined
五、定义单个属性:Object.defineProperty()
5.1 基本定义
Object.defineProperty(obj, attrName, descriptor)
:修改属性默认的特性。obj
:属性所在的对象attrName
:属性的名字descriptor
:描述符对象- 描述符对象的属性必须是:
configurable
、enumerable
、writable
和value
。 - 设置其中的一或多个值,可以修改对应的特性值。
- 描述符对象的属性必须是:
- 支持浏览器:IE9+(IE8 只是部分实现)、Firefox 4+、Safari 5+、Opera
12+ 和 Chrome 。
5.2 数据属性的有关实例
- 可读不可修改
- 这个属性的值是不可修改的,如果尝试为它指定新值,则在非严格模式下,赋值操作将被忽略;在严格模式下,赋值操作将会导 致抛出错误。
var person = {};
Object.defineProperty(person, 'name', {
writable: false,
value: "jm"
});
console.log(person.name); // "jm"
person.name = "bb";
console.log(person.name); // "jm"
- 不可配置
- 把
configurable
设置为false
,表示不能从对象中删除属性。 - 如果对这个属性调用
delete
,则在非严格模式下什么也不会发生,而在严格模式下会导致错误。 - 一旦把属性定义为不可配置的,就不能再把它变回可配置了。
- 把
var person = {};
Object.defineProperty(person, 'name', {
configurable: false,
value: "jm"
});
console.log(person.name); // "jm"
person.name = "bb";
console.log(person.name); // "jm"
// 再调用 Object.defineProperty()方法修改除 writable 之外的特性,都会导致错误:
//抛出错误
Object.defineProperty(person, "name", {
configurable: true,
value: "Nicholas"
});
在调用
Object.defineProperty()
方法时,如果不指定,configurable
、enumerable
和writable
特性的默认值都是false
。
5.3 访问器属性的有关实例
- 访问器属性不能直接定义,必须使用
Object.defineProperty()
来定义。
var book = {
_year: 2004,
editor: 1
};
Object.defineProperty(book, "year", {
get: function() {
return this._year;
},
set: function(newValue) {
if (newValue > 2004) {
this._year = newValue;
this.editor += newValue - 2004;
}
}
})
booke.year = 2005;
console.log(book.editor); // 2
- 在严格模式下,尝试写入只指定了
getter
函数的属性会抛出错误。只指定setter
函数的属性也 不能读,否则在非严格模式下会返回undefined
,而在严格模式下会抛出错误。
5.4 defineGetter()和__defineSetter__()
- 在
Object.defineProperty()
前要创建访问器属性,一般都使用两个非标准的方法:__defineGetter__()
和__defineSetter__()
。
var book = {
_year: 2004,
edition: 1
};
//定义访问器的旧有方法
book.__defineGetter__("year", function(){
return this._year;
});
book.__defineSetter__("year", function(newValue){
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
});
book.year = 2005;
alert(book.edition); //2
在不支持
Object.defineProperty()
方法的浏览器中不能修改[[Configurable]]
和[[Enumerable]]
。
六、 定义多个属性:Object.defineProperties()
Object.defineProperties(obj1, desObj)
:obj1
:要添加和修改其属性的对象desObj
:第二个对象的属性与第一个对象中要添加或修改的属性一一对应。
- 支持浏览器:IE9+、Firefox 4+、Safari 5+、Opera 12+和Chrome。
var book = {};
Object.defineProperties(book, {
_year: {
value: 2004
},
edition: {
value: 1
},
year: {
get: function(){
return this._year;
},
set: function(newValue){
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
}
});
- 以上代码在
book
对象上定义了两个数据属性(_year
和edition
)和一个访问器属性(year
)。 最终的对象与上一节中定义的对象相同。唯一的区别是这里的属性都是在同一时间创建的。
七、读取属性的特性 Object.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor(obj,descriptorName)
:obj
:属性所在的对象descriptorName
:要读取其描述符的属性名称
- 返回值是一个对象
- 如果是访问器属性,这个对象的属性有
configurable
、enumerable
、get
和set
。 - 如果是数据属性,这个对象的属性有
configurable
、enumerable
、writable
和value
。
- 如果是访问器属性,这个对象的属性有
- 支持这个方法的浏览器有 IE9+、Firefox 4+、Safari 5+、Opera 12+和 Chrome。
var book = {};
Object.defineProperties(book, {
_year: {
value: 2004
},
edition: {
value: 1
},
year: {
get: function(){
return this._year;
},
set: function(newValue){
if (newValue > 2004) {
this._year = newValue;
this.edition += newValue - 2004;
}
}
}
});
var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
alert(descriptor.value); //2004
alert(descriptor.configurable); //false
alert(typeof descriptor.get); //"undefined"
var descriptor = Object.getOwnPropertyDescriptor(book, "year");
alert(descriptor.value); //undefined
alert(descriptor.enumerable); //false
alert(typeof descriptor.get); //"function"
在 JavaScript 中,可以针对任何对象——包括
DOM
和BOM
对象,使用Object.getOwnPropertyDescriptor()
方法。
八、Object.create()
Object.create(newObj, obj)
:newObj
:用作新对象原型的对象obj
:(可选的)一个为新对象定义额外属性的对象
- 在传入一个参数的情况下,
Object.create()
与object()
方法的行为相同。 - 支持
Object.create()
方法的浏览器有 IE9+、Firefox 4+、Safari 5+、Opera 12+和 Chrome。
var person = {
name: 'jm',
friends: ['aa', 'bb', 'cc']
}
var anPerson = Object.create(person);
anPerson.name = "Greg";
anPerson.friends.push("Rob");
var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
console.log(person.friends); //"aa,bb,cc,Rob,Barbie"
console.log(person.name, anPerson.name); // jm, Greg
// 第二个参数
var anotherPerson = Object.create(person, {
name: {
value: "Greg"
}
});
alert(anotherPerson.name); //"Greg"
- 分析上述代码:
anPerson
和yetAnotherPerson
其实是person
这个对象的副本。- 对于基本类型的值是不会改变的,例如:
name
- 对于引用类型,如:数组,一变则全变。例如:
friends
- 对于基本类型的值是不会改变的,例如: