ECMAScript学习笔记(五)

Posted by Csming on 2018-09-13

面向对象程序设计

JavaScript高级程序设计的第六章。

ECMAScript的每个对象都是基于一个引用类型创建的。

理解对象

1.创建对象:

可以创建一个Object的实例,然后为它添加属性和方法。

1
2
3
4
5
6
7
8
var person = new Object();
person.name = "Micheal";
person.age = 29;
person.job = "Software Engineer";

person.sayName = function() {
alert(this.name);
};

还可以使用对象字面量创建对象:

1
2
3
4
5
6
7
8
9
var person = {
name: "Micheal",
age: 29,
job: "Software Engineer",

sayName: function() {
alert(this.name);
}
};

属性类型

ECMA定义了用于描述属性(property)的各种特征的特性(attribute)

ECMAScript中有两种属性:数据属性和访问器属性。

1.数据属性:

数据属性有四个特性:

(1)Configurable:能否通过delete删除属性从而重新定义属性,能够修改属性的特性,或者能否将属性修改为访问器类型。默认为true。
(2)Enumerable:表示能否通过for-in循环返回属性。默认为true。
(3)Writable: 表示能否修改属性的值。默认为true
(4)Value: 包含这个属性的数据值。当读取属性值的时候,从这个位置读取,写入属性值的时候,将新的值保存在这个位置。默认为undefined;

要修改属性的默认特性,则必须使用Object.defineProperty()方法。 该方法接受三个参数:属性所在的对象、属性的名字和一个描述性对象。

描述性对象必须是:configurable、enumerable、writable、value。

1
2
3
4
5
var person = {};
Object.defineProperty(person, "name", {
writable: false,
value: "Micheal"
});

可以多次调用Object.defineProperty()方法,只要configurable不为false。

另外,在调用Object.defineProperty()的时候,如果不指定,那么configurable、enumerable、writable的默认值都为false。

2.访问器属性:

访问器属性不包含数据值,它们包含一对getter和setter函数,但是这两个函数都不是必须的。

在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值。
而在写入访问器属性的时候,会调用setter函数并传入新的值,这个函数用于决定如何处理数据。

访问器属性有四个特性:

(1)Configurable:能否通过delete删除属性从而重新定义属性,能够修改属性的特性,或者能否将属性修改为访问器类型。默认为true。
(2)Enumerable:表示能否通过for-in循环返回属性。默认为true。
(3)Get: 在读取属性时调用的函数,默认为undefined
(4)Set: 在写入属性时调用的函数,默认为undefined

访问器属性不能直接定义,需要使用Object.defineProperty()。

eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var book = {
_year: 2004,
edition: 1
}

Object.defineProperty(book, "year", {
get: function() {
return this._year;
},
set: function(newValue) {
this._year = newValue;
this.edition += newValue - 2004;
}
})

book中的属性:_year前面的下划线,是一种常用的记号,用于表示只能通过对象方法访问的属性。

另外可以使用这种方法,处理访问器属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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;
}
})

定义多格属性

ECMAScript 5定义了一个Object.defineProperties()方法,用于一次性定义多个属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
}
}
}
});

读取属性的特性

可以使用ECMAScript 5的Obejct.getOwnPropertyDescriptor()方法读取属性的描述符。

eg:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
...