[轉(zhuǎn)]prototype 源碼解讀 超強(qiáng)推薦第1/3頁
更新時(shí)間:2007年02月13日 00:00:00 作者:
復(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ū)的醒來貼了自己對于prototype的源碼解讀心得,頗有借鑒意義。
我喜歡Javascript,熱衷于 Ajax 應(yīng)用。我把自己閱讀prototype源碼的體會寫下來,希望對大家重新認(rèn)識 Javascript 有所幫助。
prototype.js 代碼:
復(fù)制代碼 代碼如下:
/**
2
3 * 定義一個(gè)全局對象, 屬性 Version 在發(fā)布的時(shí)候會替換為當(dāng)前版本號
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ù)會執(zhí)行名為 initialize 的方法, initialize 是
31
32 * Ruby 對象的構(gòu)造器方法名字。
33
34 * 此時(shí)initialize方法還沒有定義,其后的代碼中創(chuàng)建新類型時(shí)會建立
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è)對象,從變量名來思考,本意也許是定義一個(gè)抽象類,以后創(chuàng)建
68
69 * 新對象都 extend 它。
70
71 * 但從其后代碼的應(yīng)用來看, Abstract 更多是為了保持命名空間清晰的考慮。
72
73 * 也就是說,我們可以給 Abstract 這個(gè)對象實(shí)例添加新的對象定義。
74
75 *
76
77 * 從java去理解,就是動(dòng)態(tài)給一個(gè)對象創(chuàng)建內(nèi)部類。
78
79 */
80
81 var Abstract = new Object();
82
83
84 /**
85
86 * 獲取參數(shù)對象的所有屬性和方法,有點(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 對象同時(shí)擁有 a 和 b 對象的屬性和方法。但是與多重繼承不同的是,
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ù)對象,返回一個(gè)新函數(shù)對象,新函
116
117 * 數(shù)對象的主體和原對象相同,但是bind()方法參數(shù)將被用作當(dāng)前對象的對象。
118
119 * 也就是說新函數(shù)中的 this 引用被改變?yōu)閰?shù)提供的對象。
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 類似??梢砸黄鹧芯肯隆?nbsp;
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控件對象的事件處理。所以要傳遞event對象
173
174 * 注意這時(shí)候,用到了 Function.call。它與 Function.apply 的不同好像僅僅是對參
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 * 然后用對象直接量的語法形式設(shè)置原型。
255
256 *
257
258 * 需要特別說明的是 rgisterCallback 方法,它調(diào)用上面定義的函數(shù)原型方法bind,
259
260 * 并傳遞自己為參數(shù)。
261
262 * 之所以這樣做,是因?yàn)?nbsp;setTimeout 默認(rèn)總以 window 對象為當(dāng)前對象,也就是說,
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 對象
343
344 * 2. 得到對象數(shù)組
345
346 * 比如: $("aaa","bbb") 返回一個(gè)包括id為
347
348 * "aaa"和"bbb"兩個(gè)input控件對象的數(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 }
相關(guān)文章
滾動(dòng)經(jīng)典最新話題[prototype框架]下編寫
滾動(dòng)經(jīng)典最新話題[prototype框架]下編寫...2006-10-10
初學(xué)prototype,發(fā)個(gè)JS接受URL參數(shù)的代碼
初學(xué)prototype,發(fā)個(gè)JS接受URL參數(shù)的代碼...2007-01-01
Prototype源碼淺析 String部分(三)之HTML字符串處理
現(xiàn)在,String部分轉(zhuǎn)入具體的關(guān)聯(lián)應(yīng)用,分別對應(yīng)HTML字符串,JSON字符串和HTML中的腳本字符串2012-01-01
Prototype Number對象 學(xué)習(xí)
這個(gè)對象提供一些操作數(shù)值類型的工具函數(shù)2009-07-07
prototype Element學(xué)習(xí)筆記(篇二)
這一篇主要是要總論Element的所有函數(shù)。2008-10-10
prototype Element學(xué)習(xí)筆記(篇一)
Element,哈哈哈。遇到正主了,到現(xiàn)在為止才遇到讓我高興的玩意。當(dāng)初Ext.Element可是花三千余行代碼專門來封裝啊。我倒要看一看它的代碼了。事實(shí)上prototype中我最想研究的只有兩個(gè)內(nèi)容:Element、Selector。這兩個(gè)東西是精華。2008-10-10
Prototype 學(xué)習(xí) Prototype對象
Prototype 學(xué)習(xí) Prototype對象2009-07-07

