最近看了一下 mootools 的核心库代码,不禁惊奇,短短几十行代码,看得目眩神迷——原来JS也可以写的这么简洁,又这么难懂 :D 也正因为以前没有像它这样使用过JS,所以倒是增加了一些对JS的认识。
JavaScript 中实现哈希表很简单:
1 | var os = new Array(); |
2 | os[ 'one' ] = 1; |
3 | os[ 'two' ] = 2; |
4 | os[ 'three' ] = 3; |
5 | |
6 | for ( var i in os) { |
7 | alert( 'key is: ' + i + ', value is: ' + os[i]); |
8 | } |
另外,在 JavaScript 中,直接支持函数指针,所以实现类的方法如下:
01 | function person(n, a) |
02 | { |
03 | this .Name = n; |
04 | this .Age = a; |
05 | this .toString = function () |
06 | { |
07 | return "Name:" + this .Name + ", Age:" + this .Age |
08 | } |
09 | } |
10 | var p = new person( "tom" , 18); |
11 | alert(p.toString()); |
那么,反射怎么做呢?
01 | function person(n, a) |
02 | { |
03 | this .Name = n; |
04 | this .Age = a; |
05 | this .toString = function () |
06 | { |
07 | return "Name:" + this .Name + ", Age:" + this .Age |
08 | } |
09 | } |
10 | var p = new person( "tom" , 18); |
11 | for ( var k in p) { |
12 | alert( 'property is: ' + k + ', value is: ' + p[k]); |
13 | } |
眼熟吧?几乎和哈希表的枚举方法一模一样,嗯,这就有个问题了,是几乎一样呢?还是根本就一样?!
在上面的代码中,p[k]就可以直接返回相应的变量的值,那么,对它赋值会怎么样?
01 | function person(n, a) |
02 | { |
03 | this .Name = n; |
04 | this .Age = a; |
05 | } |
06 | var p = new person( "tom" , 18); |
07 | p[ "toString" ] = function () |
08 | { |
09 | return "Name:" + this .Name + ", Age:" + this .Age |
10 | } |
11 | alert(p.toString()); |
大家都知道,在JS中可以用$作为函数、变量名的一部分,那么,是否只有$可以作为它的一部分呢?
01 | function person(n, a) |
02 | { |
03 | this .Name = n; |
04 | this .Age = a; |
05 | } |
06 | var p = new person( "tom" , 18); |
07 | p[ "+++" ] = function () |
08 | { |
09 | return "Name:" + this .Name + ", Age:" + this .Age |
10 | } |
11 | alert(p[ "+++" ]()); |
呵呵,好像根本可以乱整嘛 :D
01 | var os = new Array(); |
02 | os[ 'one' ] = 1; |
03 | os[ 'two' ] = 2; |
04 | os[ 'three' ] = 3; |
05 | os[ 'toString' ] = function () |
06 | { |
07 | for ( var i in this ) { |
08 | alert( 'key is: ' + i + ', value is: ' + os[i]); |
09 | } |
10 | } |
11 | os.toString(); |
吼吼,原来如此,上面也是一个类的实现喽 :D
哈希表还支持一种简洁的构造语法:
1 | var os = { |
2 | 'one' : 1, |
3 | 'two' : 2, |
4 | 'three' : 3 |
5 | } |
6 | for ( var i in os) { |
7 | alert( 'key is: ' + i + ', value is: ' + os[i]); |
8 | } |
再给它加个函数:
01 | var os = { |
02 | one: 1, |
03 | two: 2, |
04 | three: 3, |
05 | toString: function () |
06 | { |
07 | return this .one + "," + this .two + "," + this .three; |
08 | } |
09 | } |
10 | alert(os.toString()); |
嗯嗯,这也是一个类的实现。
所以,基本上可以说,在 JavaScript 中,所谓的对象,根本就是一个哈希表!或者,也许可以说,JavaScript 中的哈希表,是由对象来模拟的。
在JS中,除了object,还有 number、boolean 这几种类型,它们的情况怎么样呢?
01 | Boolean.prototype[ "toString" ] = function () |
02 | { |
03 | return "haha:" + this ; |
04 | } |
05 | var a = true ; |
06 | alert(a.toString()); |
07 | |
08 | Number.prototype[ "toString" ] = function () |
09 | { |
10 | return "hoho:" + this ; |
11 | } |
12 | var b = 20; |
13 | alert(b.toString()); |
果然是万变不离哈希啊。不过,Number 和 Boolean 稍微特殊的地方是,直接对a和b进行哈希操作无效:
1 | var a = true ; |
2 | a.toString = function () |
3 | { |
4 | return "haha:" + this ; |
5 | } |
6 | alert(a); |
那么,转化一下呢?
1 | var a = Object( true ); |
2 | a.toString = function () |
3 | { |
4 | return "haha:" + this ; |
5 | } |
6 | alert(a); |
成功~~
回到 mootools,以最简单的 implement 来说,它在 Class 上安装了一个 implement 方法,这个方法接受一个哈希表作为参数:
1 | implement: function (properties){ |
2 | for ( var property in properties) this .prototype[property] = properties[property]; |
3 | } |
使用方法如下:
1 | Animal.implement({ |
2 | setName: function (name){ |
3 | this .name = name |
4 | } |
5 | }); |
这样,就在 Animal 这个类上,扩展除了一个 setName 函数。至于复杂一些的 extend 函数,只是新建了一个实例,而不是直接操作本实例罢了。
不过,我对于 mootools 还是有一些疑惑,比如,Object.Native 究竟实干什么用的,为什么需要它,等等,还需要继续了解,继续理解。
來源:http://llf.hanzify.org/studio/article/show/521