[转]prototype 源码解读 超强推荐第1/3页
2007-02-13 00:00
841 查看
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 中文社区的醒来贴了自己对于prototype的源码解读心得,颇有借鉴意义。
我喜欢Javascript,热衷于 Ajax 应用。我把自己阅读prototype源码的体会写下来,希望对大家重新认识 Javascript 有所帮助。
prototype.js 代码:
/** 2 3 * 定义一个全局对象, 属性 Version 在发布的时候会替换为当前版本号 4 5 */ 6 7 var Prototype = { 8 9 Version: '@@VERSION@@' 10 11 } 12 13 14 /** 15 16 * 创建一种类型,注意其属性 create 是一个方法,返回一个构造函数。 17 18 * 一般使用如下 19 20 * var X = Class.create(); 返回一个类型,类似于 java 的一个 21 22 * Class实例。 23 24 * 要使用 X 类型,需继续用 new X()来获取一个实例,如同 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 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 * 创建一个对象,从变量名来思考,本意也许是定义一个抽象类,以后创建 68 69 * 新对象都 extend 它。 70 71 * 但从其后代码的应用来看, Abstract 更多是为了保持命名空间清晰的考虑。 72 73 * 也就是说,我们可以给 Abstract 这个对象实例添加新的对象定义。 74 75 * 76 77 * 从java去理解,就是动态给一个对象创建内部类。 78 79 */ 80 81 var Abstract = new Object(); 82 83 84 /** 85 86 * 获取参数对象的所有属性和方法,有点象多重继承。但是这种继承是动态获得的。 87 88 * 如: 89 90 * var a = new ObjectA(), b = new ObjectB(); 91 92 * var c = a.extend(b); 93 94 * 此时 c 对象同时拥有 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 * 这个方法很有趣,它封装一个javascript函数对象,返回一个新函数对象,新函 116 117 * 数对象的主体和原对象相同,但是bind()方法参数将被用作当前对象的对象。 118 119 * 也就是说新函数中的 this 引用被改变为参数提供的对象。 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 * 那么,调用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 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一样,不过这个方法一般用做html控件对象的事件处理。所以要传递event对象 173 174 * 注意这时候,用到了 Function.call。它与 Function.apply 的不同好像仅仅是对参 175 176 * 数形式的定义。如同 java 两个过载的方法。 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 * 将整数形式RGB颜色值转换为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 风格的函数,将参数中的方法逐个调用,返回第一个成功执行的方法的返回值 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 * 一个设计精巧的定时执行器 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 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 * 这个函数就 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 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 }
相关文章推荐
- [转]prototype 源码解读 超强推荐第1/3页
- prototype.js 源码解读v1.3.1版本
- Ajax::prototype 源码解读
- prototype 源码解读
- js技巧收集(200多个) 超强推荐第1/2页
- 创力采集程序用到的函数 推荐第1/3页
- Spring 源码解读 推荐流程
- javascript 具名函数的四种调用方式 推荐第1/3页
- prototype 源码解读
- 推荐一篇批处理最完整人性化教程第1/3页
- 创力采集程序用到的函数 推荐第1/3页
- Spring 源码解读 推荐流程
- 【Prototype 1.4.0】源码解读----全文注释版
- 源码解读jQ中浏览器兼容模块support第1/2页
- [转]Prototype 源码解读[资源]
- javascript 具名函数的四种调用方式 推荐第1/3页
- 【Prototype 1.4.0】源码解读----全文注释版
- Ajax::prototype 源码解读
- prototype.js1.4 源码解读
- [推荐]Win2003 Server安全配置完整篇第1/3页