1
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
<html xmlns="http://www.w3.org/1999/xhtml">
3
<head>
4
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
<title>定義類或對象</title>
6
<script type="text/javascript">
7
/*
8
* 項目: book -> Javascript高級程序設計.pdf -> 第3章 -> 3.5定義類或對象
9
*
10
* 說明: 以下代碼有 工廠方式,構造函數方式,原型方式,混合的構造函數+原型方式,動態原型方式,混合工廠方式定義類或對象
11
*
12
* 對JavaScript來說很有意思的一句話:構造函數只是函數,函數是對象,對象可以有屬性和方法,屬性可以是函數,函數也是類,
13
* 函數也叫方法。(一切都很抽象。^_^,對初學者來說在代碼中理解這句話很有幫助!)。
14
*
15
* 練習者: Alex刺客
16
*
17
* 日期: 2009-12-13
18
*/
19
20
/*
21
【 一 】.工廠方式
22
*/
23
24
var oCar1 = new Object;
25
oCar1.color = "red";
26
oCar1.doors = 4;
27
oCar1.mpg = 23;
28
oCar1.showColor = function () {
29
alert(this.color);
30
}
31
// oCar1.showColor();
32
33
/*
34
以上說明:因為對象的屬性可在對象創建后動態定義。
35
創建對象oCar1。然后給它設置幾個屬性:它的顏色是紅色,
36
有四個門,每加侖油可跑23英里。最后一個屬性實際上是指向函數的指針,
37
意味著該屬性是個方法。問題是這樣不能創建多個oCar1的實例。
38
39
于是就有了以下方式
40
*/
41
42
function createCar(){
43
var oTempCar = new Object;
44
oTempCar.color = "red";
45
oTempCar.doors = 4;
46
oTempCar.mpg = 23;
47
oTempCar.showColor = function () {
48
alert(this.color);
49
}
50
return oTempCar;
51
}
52
53
//var oCar1 = createCar();
54
//var oCar2 = createCar();
55
//oCar1.showColor();
56
//oCar2.showColor();
57
58
/*
59
以上說明:這樣就可以創建多個實例了,因為須要此" 類 "時可以調用createCar()
60
函數。此函數返回創建好的oTempCar" 類 "。
61
62
為了能讓他接收消息請看下面例子
63
*/
64
65
function createCar1 (sColor, iDoors, iMpg) {
66
var oTempCar = new Object;
67
oTempCar.color = sColor;
68
oTempCar.doors = iDoors;
69
oTempCar.mpg = iMpg;
70
oTempCar.showColor = function () {
71
alert(this.color);
72
}
73
return oTempCar;
74
}
75
76
//var oCar1 = createCar1('red',4,23);
77
//var oCar2 = createCar1('bule',3,18);
78
//oCar1.showColor();
79
//oCar2.showColor();
80
81
/*
82
以上說明:第1點,當我看懂這段代碼時,我才知道原來JavaScript這么有趣,
83
對象可以不用 new !用new 也一樣的結果。而且每次調用函數createCar1(),
84
都要創建新函數showColor(),意味著每個對象都有自己的showColor()版本。
85
事實上,每個對象都共享了同一個函數。
86
87
為了消除反復創建函數showColor() 繼續往下看
88
*/
89
90
function showColor () {
91
alert(this.color);
92
}
93
94
function createCar2 (sColor, iDoors, iMpg) {
95
var oTempCar = new Object;
96
oTempCar.color = sColor;
97
oTempCar.doors = iDoors;
98
oTempCar.mpg = iMpg;
99
oTempCar.showColor = showColor;
100
return oTempCar;
101
}
102
103
//var oCar1 = createCar2("red", 4, 23);
104
//var oCar2 = createCar2("blue", 3, 18);
105
//oCar1.showColor();
106
//oCar2.showColor();
107
108
/*
109
以上說明:在createCar2()函數之前定義showColor()方法,在createCar2()內部,
110
賦予對象一個指向已經存在的showColor()函數的指針。這樣解決了重復創建函數
111
對象的問題.。但該函數看起來不像對象的方法。
112
*/
113
114
/*
115
【 二 】構造函數方式
116
Car在這也叫函數名,也叫類名
117
*/
118
function Car (sColor, iDoors, iMpg) {
119
this.color = sColor;
120
this.doors =iDoors;
121
this.mpg = iMpg;
122
this.showColor = function () {
123
alert(this.color);
124
}
125
}
126
127
//var oCar1 = new Car("red", 4, 23);
128
//var oCar2 = new Car("blue", 3, 18);
129
//oCar1.showColor();
130
//oCar2.showColor();
131
132
/*
133
以上說明:構造函數內部不再創建Object對象,而是使用了this關鍵字,所以要
134
使用new運算符來調用該構造函數(即所謂的" 類 "),同是在執行第一行代碼前先創
135
建一個對象,只有用this才能訪問該對象(當前new所創建的對象)。然后可直接賦予this屬性,默認情況下是
136
構造函數的返回值(不必明確使用 return)。但這種方式就像工廠函數一樣,也會重復
137
生成showColor()函數。
138
*/
139
140
/*
141
【 三 】原型方式
142
看見這原型這兩個字,就讓我想起了虐殺原型^_^。
143
144
這種方式利用了對象的prototype屬性,可把它看成創建新對象所依賴的原型,
145
這里,用空構造函數來設置類名。然后所有的屬性和方法都被直接賦予prototype屬性。
146
*/
147
148
function Car1() {}
149
150
Car1.prototype.color = "red";
151
Car1.prototype.doors = 4;
152
Car1.prototype.mpg = 23;
153
Car1.prototype.drivers = new Array("Mike","Sue");
154
Car1.prototype.showColor = function () {
155
alert(this.color);
156
}
157
158
//var oCar11 = new Car1();
159
//var oCar12 = new Car1();
160
161
/*
162
以上說明: 首先定義函數 Car1 ,基中無任何代碼,再通過給 Car1 的prototype 屬性添加
163
屬性(color,doors,mpg,showColor)去定義Car1對象的屬性。調用new Car1() 時,原型
164
所有屬性都被立即賦予要創建的對象,意味著所有Car1實例存方的都是指向showColor()函
165
數的指針。從語義上講,所有屬性看起來都屬于一個對象。使用該方法還能用instanceof運算符
166
檢查給定變量的對象類型。
167
alert(oCar11 instanceof Car1); // true
168
169
但是:因為所有屬性都是用了prototype屬性定義的,所以問題又出來了。
170
*/
171
172
//var oCar11 = new Car1();
173
//var oCar12 = new Car1();
174
175
//oCar11.drivers.push("Matt");
176
177
//alert(oCar11.drivers);
178
//alert(oCar12.drivers);
179
180
/*
181
以上說明:因為Car1類的對象的drivers屬性是一個Array數組對象的引用(指向它的指針),
182
當Array數組對象發生變化時,所有Car1的對象的drivers屬性都指向同一個Array數組,
183
所以就產生了以上結果。
184
*/
185
186
/*
187
【 四 】混合的構造函數+原型方式
188
*/
189
190
function Car2 (sColor, iDoors, iMpg) {
191
this.color = sColor;
192
this.doors = iDoors;
193
this.mpg =iMpg;
194
this.drivers = new Array("Mike","sue");
195
}
196
197
Car2.prototype.showColor = function (){
198
alert(this.color);
199
}
200
201
//var oCar21 = new Car2("red",4,23);
202
//var oCar22 = new Car2("blue",3,18);
203
204
//oCar21.drivers.push("Matt");
205
206
//alert( oCar21.drivers);
207
//alert( oCar22.drivers);
208
209
/*
210
以上說明: 用構造函數定義對象的所有非函數屬性,用原型方式定義對象的函數(方法)。
211
結果所有函數都只創建一次,而每個對象都具有自己的對象屬性的實例。所有的非函數
212
屬性都在構造函數中創建,意味著又可用構造函數的參數賦予對象屬性的默認值。因為
213
Car2類的showColor()函數是用原型屬性定義的,所以Car2類的實例都共同擁有指
214
向showColor()方法的指針.所以沒有浪費內存。
215
*/
216
217
/*
218
【 五 】動態原型方式
219
上面的方法唯一點遺憾就是在Car2類外面定義的showColor()方法.
220
這個就是為了更完美!
221
*/
222
223
function Car3 (sColor, iDoors, iMpg) {
224
this.color = sColor;
225
this.doors = iDoors;
226
this.mpg = iMpg;
227
this.drivers = new Array("mike","sue");
228
if(typeof Car3._initialized == "undefined"){
229
Car3.prototype.showColor = function (){
230
alert(this.color);
231
}
232
Car3._initialized = true;
233
alert("以后我都不執行了!");
234
}
235
}
236
237
var car31 = new Car3("red",4,23);
238
var car33 = new Car3("blue",3,18);
239
240
/*
241
以上說明:因為只在Car3類第一次創建實例時,只執行一次創建showColor()方法.
242
再以后創建Car3類的實例時都不執行了。而且這個類的全部成員,都在此類內部,
243
看著更像一個類。
244
*/
245
246
/*
247
【 六 】混合工廠方式
248
249
這個方式我至今還沒看懂,只在工廠方式定義好的函數前使用了一個new 不知道有什么好處!
250
請高手賜教!
251
*/
252
253
function Car4 () {
254
var oTempCar = new Object;
255
oTempCar.color = "red";
256
oTempCar.doors = 4;
257
oTempCar.mpg = 23;
258
oTempCar.showColor = function () {
259
alert(this.color);
260
}
261
return oTempCar;
262
}
263
264
var cat4 = new Car4();
265
266
/*
267
提示:在jjavaScritpt中創建類最好的方式是用構造函數定義屬性,用原型定義方法。
268
*/
269
</script>
270
</head>
271
<body>
272
</body>
273
</html>

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

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273
