|
復(fù)制代碼 代碼如下:
Prototype is a JavaScript framework that aims to ease development of dynamic web applications. Featuring a unique, easy-to-use toolkit for class-driven development and the nicest Ajax library around, Prototype is quickly becoming the codebase of choice for Web 2.0 developers everywhere.Ruby On Rails 中文社區(qū)的醒來貼了自己對(duì)于prototype的源碼解讀心得,頗有借鑒意義。
我喜歡Javascript,熱衷于 Ajax 應(yīng)用。我把自己閱讀prototype源碼的體會(huì)寫下來,希望對(duì)大家重新認(rèn)識(shí) Javascript 有所幫助。
prototype.js 代碼:
復(fù)制代碼 代碼如下:
/**
2
3 * 定義一個(gè)全局對(duì)象, 屬性 Version 在發(fā)布的時(shí)候會(huì)替換為當(dāng)前版本號(hào)
4
5 */
6
7 var Prototype = {
8
9 Version: '@@VERSION@@'
10
11 }
12
13
14 /**
15
16 * 創(chuàng)建一種類型,注意其屬性 create 是一個(gè)方法,返回一個(gè)構(gòu)造函數(shù)。
17
18 * 一般使用如下
19
20 * var X = Class.create(); 返回一個(gè)類型,類似于 Java 的一個(gè)
21
22 * Class實(shí)例。
23
24 * 要使用 X 類型,需繼續(xù)用 new X()來獲取一個(gè)實(shí)例,如同 Java 的
25
26 * Class.newInstance()方法。
27
28 *
29
30 * 返回的構(gòu)造函數(shù)會(huì)執(zhí)行名為 initialize 的方法, initialize 是
31
32 * Ruby 對(duì)象的構(gòu)造器方法名字。
33
34 * 此時(shí)initialize方法還沒有定義,其后的代碼中創(chuàng)建新類型時(shí)會(huì)建立
35
36 * 相應(yīng)的同名方法。
37
38 *
39
40 * 如果一定要從Java上去理解。你可以理解為用Class.create()創(chuàng)建一個(gè)
41
42 * 繼承Java.lang.Class類的類。
43
44 * 當(dāng)然Java不允許這樣做,因?yàn)镃lass類是final的
45
46 *
47
48 */
49
50 var Class = {
51
52 create: function() {
53
54 return function() {
55
56 this.initialize.apply(this, arguments);
57
58 }
59
60 }
61
62 }
63
64
65 /**
66
67 * 創(chuàng)建一個(gè)對(duì)象,從變量名來思考,本意也許是定義一個(gè)抽象類,以后創(chuàng)建
68
69 * 新對(duì)象都 extend 它。
70
71 * 但從其后代碼的應(yīng)用來看, Abstract 更多是為了保持命名空間清晰的考慮。
72
73 * 也就是說,我們可以給 Abstract 這個(gè)對(duì)象實(shí)例添加新的對(duì)象定義。
74
75 *
76
77 * 從Java去理解,就是動(dòng)態(tài)給一個(gè)對(duì)象創(chuàng)建內(nèi)部類。
78
79 */
80
81 var Abstract = new Object();
82
83
84 /**
85
86 * 獲取參數(shù)對(duì)象的所有屬性和方法,有點(diǎn)象多重繼承。但是這種繼承是動(dòng)態(tài)獲得的。
87
88 * 如:
89
90 * var a = new ObjectA(), b = new ObjectB();
91
92 * var c = a.extend(b);
93
94 * 此時(shí) c 對(duì)象同時(shí)擁有 a 和 b 對(duì)象的屬性和方法。但是與多重繼承不同的是,
95
96 * c instanceof ObjectB 將返回false。
97
98 */
99
100 Object.prototype.extend = function(object) {
101
102 for (property in object) {
103
104 this[property] = object[property];
105
106 }
107
108 return this;
109
110 }
111
112
113 /**
114
115 * 這個(gè)方法很有趣,它封裝一個(gè)Javascript函數(shù)對(duì)象,返回一個(gè)新函數(shù)對(duì)象,新函
116
117 * 數(shù)對(duì)象的主體和原對(duì)象相同,但是bind()方法參數(shù)將被用作當(dāng)前對(duì)象的對(duì)象。
118
119 * 也就是說新函數(shù)中的 this 引用被改變?yōu)閰?shù)提供的對(duì)象。
120
121 * 比如:
122
123 * <input type="text" id="aaa" value="aaa">
124
125 * <input type="text" id="bbb" value="bbb">
126
127 * .................
128
129 * <script>
130
131 * var aaa = document.getElementById("aaa");
132
133 * var bbb = document.getElementById("bbb");
134
135 * aaa.showValue = function() {alert(this.value);}
136
137 * aaa.showValue2 = aaa.showValue.bind(bbb);
138
139 * </script>
140
141 * 那么,調(diào)用aaa.showValue 將返回"aaa",
142
143 * 但調(diào)用aaa.showValue2 將返回"bbb"。
144
145 *
146
147 * apply 是ie5.5后才出現(xiàn)的新方法(NETscape好像很早就支持了)。
148
149 * 該方法更多的資料參考MSDN
150
151 * http://msdn.microsoft.com/library/en-us/script56/html/js56jsmthApply.ASP
152
153 * 還有一個(gè) call 方法,應(yīng)用起來和 apply 類似。可以一起研究下。
154
155 */
156
157 Function.prototype.bind = function(object) {
158
159 var method = this;
160
161 return function() {
162
163 method.apply(object, arguments);
164
165 }
166
167 }
168
169
170 /**
171
172 * 和bind一樣,不過這個(gè)方法一般用做html控件對(duì)象的事件處理。所以要傳遞event對(duì)象
173
174 * 注意這時(shí)候,用到了 Function.call。它與 Function.apply 的不同好像僅僅是對(duì)參
175
176 * 數(shù)形式的定義。如同 Java 兩個(gè)過載的方法。
177
178 */
179
180 Function.prototype.bindAsEventListener = function(object) {
181
182 var method = this;
183
184 return function(event) {
185
186 method.call(object, event || window.event);
187
188 }
189
190 }
191
192
193 /**
194
195 * 將整數(shù)形式RGB顏色值轉(zhuǎn)換為HEX形式
196
197 */
198
199 Number.prototype.toColorPart = function() {
200
201 var digits = this.toString(16);
202
203 if (this < 16) return '0' + digits;
204
205 return digits;
206
207 }
208
209
210 /**
211
212 * 典型 Ruby 風(fēng)格的函數(shù),將參數(shù)中的方法逐個(gè)調(diào)用,返回第一個(gè)成功執(zhí)行的方法的返回值
213
214 */
215
216 var Try = {
217
218 these: function() {
219
220 var returnValue;
221
222
223 for (var i = 0; i < arguments.length; i++) {
224
225 var lambda = arguments[i];
226
227 try {
228
229 returnValue = lambda();
230
231 break;
232
233 } catch (e) {}
234
235 }
236
237
238 return returnValue;
239
240 }
241
242 }
243
244
245 /*--------------------------------------------------------------------------*/
246
247
248 /**
249
250 * 一個(gè)設(shè)計(jì)精巧的定時(shí)執(zhí)行器
251
252 * 首先由 Class.create() 創(chuàng)建一個(gè) PeriodicalExecuter 類型,
253
254 * 然后用對(duì)象直接量的語法形式設(shè)置原型。
255
256 *
257
258 * 需要特別說明的是 rgisterCallback 方法,它調(diào)用上面定義的函數(shù)原型方法bind,
259
260 * 并傳遞自己為參數(shù)。
261
262 * 之所以這樣做,是因?yàn)?nbsp;setTimeout 默認(rèn)總以 window 對(duì)象為當(dāng)前對(duì)象,也就是說,
263
264 * 如果 registerCallback 方法定義如下的話:
265
266 * registerCallback: function() {
267
268 * setTimeout(this.onTimerEvent, this.frequency * 1000);
269
270 * }
271
272 * 那么,this.onTimeoutEvent 方法執(zhí)行失敗,因?yàn)樗鼰o法
273
274 * 訪問 this.currentlyExecuting 屬性。
275
276 * 而使用了bind以后,該方法才能正確的找到this,
277
278 * 也就是PeriodicalExecuter的當(dāng)前實(shí)例。
279
280 */
281
282 var PeriodicalExecuter = Class.create();
283
284 PeriodicalExecuter.prototype = {
285
286 initialize: function(callback, frequency) {
287
288 this.callback = callback;
289
290 this.frequency = frequency;
291
292 this.currentlyExecuting = false;
293
294
295 this.registerCallback();
296
297 },
298
299
300 registerCallback: function() {
301
302 setTimeout(this.onTimerEvent.bind(this), this.frequency * 1000);
303
304 },
305
306
307 onTimerEvent: function() {
308
309 if (!this.currentlyExecuting) {
310
311 try {
312
313 this.currentlyExecuting = true;
314
315 this.callback();
316
317 } finally {
318
319 this.currentlyExecuting = false;
320
321 }
322
323 }
324
325
326 this.registerCallback();
327
328 }
329
330 }
331
332
333 /*--------------------------------------------------------------------------*/
334
335
336 /**
337
338 * 這個(gè)函數(shù)就 Ruby 了。我覺得它的作用主要有兩個(gè)
339
340 * 1. 大概是 document.getElementById(id) 的最簡化調(diào)用。
341
342 * 比如:$("aaa") 將返回上 aaa 對(duì)象
343
344 * 2. 得到對(duì)象數(shù)組
345
346 * 比如: $("aaa","bbb") 返回一個(gè)包括id為
347
348 * "aaa"和"bbb"兩個(gè)input控件對(duì)象的數(shù)組。
349
350 */
351
352 function $() {
353
354 var elements = new Array();
355
356
357 for (var i = 0; i < arguments.length; i++) {
358
359 var element = arguments[i];
360
361 if (typeof element == 'string')
362
363 element = document.getElementById(element);
364
365
366 if (arguments.length == 1)
367
368 return element;
369
370
371 elements.push(element);
372
373 }
374
375
376 return elements;
377
378 }
JavaScript技術(shù):[轉(zhuǎn)]prototype 源碼解讀 超強(qiáng)推薦第1/3頁,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。