ECMA-262将对象定义为一组属性的无序集合,即对象是一组没有特定顺序的值。对象的每个属性或方法由一个名称标识,名称映射到一个值。可以将ECMAScript的对象看作一个散列表,内容为一组名/值对,值可以是数据和函数。
1.自定义对象
创建自定义对象的方式是创建一个Object的新实例,给该实例添加属性和方法。
let Person = new Object();
Person.name = 'Jack';
Person.age = 16;
Person.job = 'Software Enginner';
Person.sayName = function(){
console.log(this.name);
};
以上代码创建了一个名为Person的对象,该对象有3个属性(name,age 和 job)和1个方法(sayName()),该方法打印this.name的值。
一种新的创建自定义对象的属性。
let person = {
name: 'Jack' ,
age: 26 ,
job: 'Software Enginner' ,
sayName() {
console.log(this.name)
},
};
2.属性的分类
ECMA - 262使用一些内部属性来描述属性的特征。为了将某个特性标识为内部属性,规范使用两个中括号包含起来。
属性分为数据属性和访问器属性。
1.数据属性
数据属性包含一个保存数据值的位置。数据值从该位置读取,也会写入该位置。数据属性由4个特性描述他们的行为。
- [[Configurable]]: 表示属性是否通过delete删除并重新定义,是否可以修改其特性,以及是否可以将其改为访问器属性,一般情况下直接定义在对象上的属性的该特性为
true
。 - [[ Enumerable]]: 表示属性是否可以通过
for-in
循环返回,默认直接定义在对象上的属性的该特性为true
。 - [[Writable]]: 表示属性的值是否可以被修改,默认直接定义在对象上的属性的该特性为
true
。 - [[ Value ]]: 包括属性的实际值。该特性默认为undefined。
修改属性的默认特性,需要使用Object.defineProperty方法。该方法接收3个参数:给其添加属性的对象、属性的名称、属性的特性描述符对象。最后一个描述符对象包含:configurable、enumerable、writable 和 value。
let person = {};
Object.defineProperty(person, "name", {
writable: false,
value: "Jack"
});
console.log(person.name) ; //Jack
person.name = "Jhon";
console.log(person.name) //Jack
上述代码块为person添加name属性,并将name属性修改为不可修改特性。
let person = {};
Object.defineProperty(person, "name", {
configurable: false,
value: "Jack"
});
console.log(person.name) ; //Jack
delete person.name;
console.log(person.name) //Jack
上述代码为person对象添加name属性,并将configurable设置为false
,意味着该属性不可删除。一个属性被配置为不可配置之后,就不会再改回之前的配置。
对同一属性可以多次调用Object.defineProperty(),单将configurable设置为false之后就受限。在调用Object.defineProperty()时,configurable、enumerable和writable的值如果不指定,默认为false
。
2.访问器属性
访问器属性包含一个获取函数getter
和一个设置函数setter
,在读取访问器属性时,会调用getter
函数,返回一个有效值;在写入访问器属性,会调用setter
函数传入新值。
- [[Configurable]]: 表示属性是否通过delete删除并重新定义,是否可以修改其特性,以及是否可以将其改为数据属性,一般情况下直接定义在对象上的属性的该特性为
true
。 - [[ Enumerable]]: 表示属性是否可以通过
for-in
循环返回,默认直接定义在对象上的属性的该特性为true
。 - [[Get]]: 获取函数,在读取属性时调用。默认为undefined。
- [[ Set]]:设置函数,在写入属性时调用,默认为undefined。
访问器属性需要使用Object.defineProperty()。
let book = {
year_: 2017 ,
edtion: 1
}
Object.defineProperty(book, "year",{
get() {
return this.year_;
},
set(newValue){
if(newValue > 2017){
this.year_ = newValue;
this.edition += newValue - 2017;
}
})
book.year = 2018;
console.log(book.edition); //2