[转]prototype 源码解读 超强推荐第1/3页

时间:2021-05-28

复制代码 代码如下:
PrototypeisaJavaScriptframeworkthataimstoeasedevelopmentofdynamicwebapplications.Featuringaunique,easy-to-usetoolkitforclass-drivendevelopmentandthenicestAjaxlibraryaround,PrototypeisquicklybecomingthecodebaseofchoiceforWeb2.0developerseverywhere.RubyOnRails中文社区的醒来贴了自己对于prototype的源码解读心得,颇有借鉴意义。

我喜欢Javascript,热衷于Ajax应用。我把自己阅读prototype源码的体会写下来,希望对大家重新认识Javascript有所帮助。

prototype.js代码:
复制代码 代码如下:
/**
2
3*定义一个全局对象,属性Version在发布的时候会替换为当前版本号
4
5*/
6
7varPrototype={
8
9Version:'@@VERSION@@'
10
11}
12
13
14/**
15
16*创建一种类型,注意其属性create是一个方法,返回一个构造函数。
17
18*一般使用如下
19
20*varX=Class.create();返回一个类型,类似于java的一个
21
22*Class实例。
23
24*要使用X类型,需继续用newX()来获取一个实例,如同java的
25
26*Class.newInstance()方法。
27
28*
29
30*返回的构造函数会执行名为initialize的方法,initialize是
31
32*Ruby对象的构造器方法名字。
33
34*此时initialize方法还没有定义,其后的代码中创建新类型时会建立
35
36*相应的同名方法。
37
38*
39
40*如果一定要从java上去理解。你可以理解为用Class.create()创建一个
41
42*继承java.lang.Class类的类。
43
44*当然java不允许这样做,因为Class类是final的
45
46*
47
48*/
49
50varClass={
51
52create:function(){
53
54returnfunction(){
55
56this.initialize.apply(this,arguments);
57
58}
59
60}
61
62}
63
64
65/**
66
67*创建一个对象,从变量名来思考,本意也许是定义一个抽象类,以后创建
68
69*新对象都extend它。
70
71*但从其后代码的应用来看,Abstract更多是为了保持命名空间清晰的考虑。
72
73*也就是说,我们可以给Abstract这个对象实例添加新的对象定义。
74
75*
76
77*从java去理解,就是动态给一个对象创建内部类。
78
79*/
80
81varAbstract=newObject();
82
83
84/**
85
86*获取参数对象的所有属性和方法,有点象多重继承。但是这种继承是动态获得的。
87
88*如:
89
90*vara=newObjectA(),b=newObjectB();
91
92*varc=a.extend(b);
93
94*此时c对象同时拥有a和b对象的属性和方法。但是与多重继承不同的是,
95
96*cinstanceofObjectB将返回false。
97
98*/
99
100Object.prototype.extend=function(object){
101
102for(propertyinobject){
103
104this[property]=object[property];
105
106}
107
108returnthis;
109
110}
111
112
113/**
114
115*这个方法很有趣,它封装一个javascript函数对象,返回一个新函数对象,新函
116
117*数对象的主体和原对象相同,但是bind()方法参数将被用作当前对象的对象。
118
119*也就是说新函数中的this引用被改变为参数提供的对象。
120
121*比如:
122
123*<inputtype="text"id="aaa"value="aaa">
124
125*<inputtype="text"id="bbb"value="bbb">
126
127*.................
128
129*<script>
130
131*varaaa=document.getElementById("aaa");
132
133*varbbb=document.getElementById("bbb");
134
135*aaa.showValue=function(){alert(this.value);}
136
137*aaa.showValue2=aaa.showValue.bind(bbb);
138
139*</script>
140
141*那么,调用aaa.showValue将返回"aaa",
142
143*但调用aaa.showValue2将返回"bbb"。
144
145*
146
147*apply是ie5.5后才出现的新方法(Netscape好像很早就支持了)。
148
149*该方法更多的资料参考MSDN
150
151*http://msdn.microsoft.com/library/en-us/script56/html/js56jsmthApply.asp
152
153*还有一个call方法,应用起来和apply类似。可以一起研究下。
154
155*/
156
157Function.prototype.bind=function(object){
158
159varmethod=this;
160
161returnfunction(){
162
163method.apply(object,arguments);
164
165}
166
167}
168
169
170/**
171
172*和bind一样,不过这个方法一般用做html控件对象的事件处理。所以要传递event对象
173
174*注意这时候,用到了Function.call。它与Function.apply的不同好像仅仅是对参
175
176*数形式的定义。如同java两个过载的方法。
177
178*/
179
180Function.prototype.bindAsEventListener=function(object){
181
182varmethod=this;
183
184returnfunction(event){
185
186method.call(object,event||window.event);
187
188}
189
190}
191
192
193/**
194
195*将整数形式RGB颜色值转换为HEX形式
196
197*/
198
199Number.prototype.toColorPart=function(){
200
201vardigits=this.toString(16);
202
203if(this<16)return'0'+digits;
204
205returndigits;
206
207}
208
209
210/**
211
212*典型Ruby风格的函数,将参数中的方法逐个调用,返回第一个成功执行的方法的返回值
213
214*/
215
216varTry={
217
218these:function(){
219
220varreturnValue;
221
222
223for(vari=0;i<arguments.length;i++){
224
225varlambda=arguments[i];
226
227try{
228
229returnValue=lambda();
230
231break;
232
233}catch(e){}
234
235}
236
237
238returnreturnValue;
239
240}
241
242}
243
244
245
246
247
248/**
249
250*一个设计精巧的定时执行器
251
252*首先由Class.create()创建一个PeriodicalExecuter类型,
253
254*然后用对象直接量的语法形式设置原型。
255
256*
257
258*需要特别说明的是rgisterCallback方法,它调用上面定义的函数原型方法bind,
259
260*并传递自己为参数。
261
262*之所以这样做,是因为setTimeout默认总以window对象为当前对象,也就是说,
263
264*如果registerCallback方法定义如下的话:
265
266*registerCallback:function(){
267
268*setTimeout(this.onTimerEvent,this.frequency*1000);
269
270*}
271
272*那么,this.onTimeoutEvent方法执行失败,因为它无法
273
274*访问this.currentlyExecuting属性。
275
276*而使用了bind以后,该方法才能正确的找到this,
277
278*也就是PeriodicalExecuter的当前实例。
279
280*/
281
282varPeriodicalExecuter=Class.create();
283
284PeriodicalExecuter.prototype={
285
286initialize:function(callback,frequency){
287
288this.callback=callback;
289
290this.frequency=frequency;
291
292this.currentlyExecuting=false;
293
294
295this.registerCallback();
296
297},
298
299
300registerCallback:function(){
301
302setTimeout(this.onTimerEvent.bind(this),this.frequency*1000);
303
304},
305
306
307onTimerEvent:function(){
308
309if(!this.currentlyExecuting){
310
311try{
312
313this.currentlyExecuting=true;
314
315this.callback();
316
317}finally{
318
319this.currentlyExecuting=false;
320
321}
322
323}
324
325
326this.registerCallback();
327
328}
329
330}
331
332
333
334
335
336/**
337
338*这个函数就Ruby了。我觉得它的作用主要有两个
339
340*1.大概是document.getElementById(id)的最简化调用。
341
342*比如:$("aaa")将返回上aaa对象
343
344*2.得到对象数组
345
346*比如:$("aaa","bbb")返回一个包括id为
347
348*"aaa"和"bbb"两个input控件对象的数组。
349
350*/
351
352function$(){
353
354varelements=newArray();
355
356
357for(vari=0;i<arguments.length;i++){
358
359varelement=arguments[i];
360
361if(typeofelement=='string')
362
363element=document.getElementById(element);
364
365
366if(arguments.length==1)
367
368returnelement;
369
370
371elements.push(element);
372
373}
374
375
376returnelements;
377
378}
123下一页阅读全文

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章