日期:2014-05-16  浏览次数:20343 次

【转】从 prototype.js 深入学习 javascript 的面向对象特性

从 prototype.js 深入学习 javascript 的面向对象特性

js是一门很强大的语言,灵活,方便。 目前我接触到的语言当中,从语法角度上讲,只有 Ruby 比它更爽。

不过我接触的动态语言只有: js ruby python flash的as 简单的几门, 应该算是井底之蛙之见。

js 语法成分简单,没有 ruby 语言复杂。所以有时候我觉得她更干净(Ruby Fans 不要攻击我哦,我也是很爱很爱很爱Ruby的)!

prototype.js 无疑是 js的漂亮之作,从它身上应该可以学到一些东西。

如果你用 js 在页面仅仅能写出 if, alert等简单的验证代码,或者想多了解一下Js, 那么此文可能对你有帮助。

好了,开始吧。

现在我突然想起了 Thinking in java?中的 "一切皆是对像", 其实我觉得这句话 有点不适合 java 反倒是更适合 js


1.怎样构造(初始化)对象?

var Prototype = {    
  Version: '1.5.0_rc1',    
  ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)',    
  emptyFunction: function() {},    
  K: function(x) {return x}    
}  

就这样,初始化了一个对象(名字就叫 Prototype),以及对象的四个成员: Version, ScriptFragment, emptyFunction, K

我们也来试试:

var bbs = {    
 name: 'JavaEye',    
 version: '2.0',    
 describe: "做最棒的软件开发交流区",    
 sayHello: function() { alert("hello, i'm javaeye! ") }    
}   

于是你可以这样使用: bbs.name 或 bbs.sayHello()

看到吗? sayHello 是一个方法哦,不要惊慌,"一切都是对象",所以它和 name 是一样的,只不过初始化,或定义的语法不一样。想起 js 中的正则表达式中的那两个杆杆了吗? 可爱吧!

方法是对象,所以它可以被当作参数传递,或者作为方法的返回值。

所以 Prototype 中有一个 Version 属性,还有一个匹配 script 的正则式字符串, 一个空方法emptyFunction,还有一个方法 K, 它仅仅返回参数。

没问题吧,继续!

2. 构造函数?

先让我们写段代码吧(中学时,我语文极差(大学没语文了),我想写代码让你们明白我心里真实的想法):

var Person = function(name) { // 这里 Person 是一个方法    
 this.name = name;    
}    
var bencode = new Persion("bencode");  // 这里像Java吧!    
alert(bencode.name);   

先看结果:
从 alert(bencode.name); 可以知道,bencode是对象, 而 name 就是 bencode 的属性, 它被正确地初始化为 "bencode"

所以 var bencode = new Persion("bencode"); 就是构造了一个新的对象,Person() 相当于构造函数

所以 new 这个关键字, 就是构造一个新的对象,并且在这个对象上调用相应的方法,并将这个对象返回。

按上面说: 方法 如果用在 在 new 后面,就相当于成了构造函数了。

话又说回来了, 如果 var bencode = new Persion("bencode") 是 构造了一个对象,像Java, 那么 Person 是不是类呢?
可是 Person 不是方法吗? 可是方法不也是对象吗? 类也是对象?

一切皆对象?

本来无一物!

好了,看 prototype.js吧

var Class = {    
  create: function() {    
    return function() {    
      this.initialize.apply(this, arguments);    
    }    
  }    
}  

初始化一个 Class 对象, 它有一个成员,是一个方法, 这个方法返因另一个方法(方法是对象,所以可以作为参数或者返回值)

所以如果我们这么做:

var A = Class.create(); // 此时 A 是一个方法,方法体,下面解释    
var a = new A(...);  // 对方法使用 new 操作符,就是构造一个新的对象,然后在这个对象上调用这个方法( 现在是 A)   

上面分析说? A相当于类, 哈哈 Class.create();??// 终于名副其实
var a = new A(...);??// 也是相当地直观, 就是构造一个新的对象,类型 是A

new 操作符构造了对象,并调用了 方法, 这个方法到底做了什么呢? 也就是上面没有分析的东东,看看先:

var Class = {    
  create: function() {    
    return function() {  // 见[1]    
      this.initialize.apply(this, arguments);  // 见[2]    
    }    
  }     
}   

?

[1]. new 操作符,就会在新产生的对象上调用这个方法
[2]. 哦? 这里就是调用 this 对象上的 initialize方法, 并传递 arguments
? 换句话说,就是把构造的任务委托给 initialize 方法
? initialize? 哪里来? 见下面,类的扩展(继承)
[3]. prototype?

看段老代码:

var Person = function(name) {    
 this.name = name;    
}    
var bencode = new Person("bencode");  

bencode不是一个自闭的人,他应该可以向javaeye介绍一下自己。
像这样:

bencode.sayHello();    

假如不能实现以上功能的话, 上面的 new,上面所有的东东都等于垃圾。

所以。需要给 Person 类加"实例方法"

题外话: 静态方法如何添加? 看上面的 Class.create, 仅仅是一个对象的成员而已

好, 再来一段 (为了完整性,上面的几句话,再抄一次)

var Person = function(name) {    
 this.name = name;    
}    
Person.prototype = {  // protype 是啥?    
 sayHello: