js 建立類

js是一門很強大的語言,靈活,方便。 目前我接觸到的語言當中,從語法角度上講,只有 Ruby 比它更爽。html

不過我接觸的動態語言只有: js ruby python flash的as 簡單的幾門, 應該算是井底之蛙之見。java

js 語法成分簡單,沒有 ruby 語言複雜。因此有時候我以爲她更乾淨(Ruby Fans 不要***我哦,我也是很愛很愛很愛Ruby的)!python

Prototype.js 無疑是 js的漂亮之做,從它身上應該能夠學到一些東西。ajax

若是你用 js 在頁面僅僅能寫出 if, alert等簡單的驗證代碼,或者想多瞭解一下Js, 那麼此文可能對你有幫助。正則表達式

好了,開始吧。ruby

如今我忽然想起了 Thinking in java 中的 "一切皆是對像", 其實我以爲這句話 有點不適合 java 反卻是更適合 jsapp


1.怎樣構造(初始化)對象?ide

js 代碼
  1. var Prototype = { 函數

  2. Version: '1.5.0_rc1', this

  3. ScriptFragment: '(?:)((\n|\r|.)*?)(?:<\/script>)',

  4. emptyFunction: function() {},

  5. K: function(x) {return x}

  6. }

就這樣,初始化了一個對象(名字就叫 Prototype),以及對象的四個成員: Version, ScriptFragment, emptyFunction, K

咱們也來試試:

js 代碼
  1. var bbs = {

  2. name: 'JavaEye',

  3. version: '2.0',

  4. describe: "作最棒的軟件開發交流區",

  5. sayHello: function() { alert("hello, i'm javaeye! ") }

  6. }

因而你能夠這樣使用: bbs.name 或 bbs.sayHello()

看到嗎? sayHello 是一個方法哦,不要驚慌,"一切都是對象",因此它和 name 是同樣的,只不過初始化,或定義的語法不同。想起 js 中的正則表達式中的那兩個杆杆了嗎? 可愛吧!

方法是對象,因此它能夠被看成參數傳遞,或者做爲方法的返回值。

因此 Prototype 中有一個 Version 屬性,還有一個匹配 script 的正則式字符串, 一個空方法emptyFunction,還有一個方法 K, 它僅僅返回參數。

沒問題吧,繼續!

2. 構造函數?

先讓咱們寫段代碼吧(中學時,我語文極差(大學沒語文了),我想寫代碼讓大家明白我內心真實的想法):

js 代碼
  1. var Person = function(name) { // 這裏 Person 是一個方法

  2. this.name = name;

  3. }

  4. var bencode = new Persion("bencode"); // 這裏像Java吧!

  5. 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吧

js 代碼
  1. var Class = {

  2. create: function() {

  3. returnfunction() {

  4. this.initialize.apply(this, arguments);

  5. }

  6. }

  7. }

初始化一個 Class 對象, 它有一個成員,是一個方法, 這個方法返因另外一個方法(方法是對象,因此能夠做爲參數或者返回值)

因此若是咱們這麼作:

js 代碼
  1. var A = Class.create(); // 此時 A 是一個方法,方法體,下面解釋

  2. var a = new A(...); // 對方法使用 new 操做符,就是構造一個新的對象,而後在這個對象上調用這個方法( 如今是 A)

上面分析說? A至關於類, 哈哈 Class.create(); // 終於名副其實
var a = new A(...); // 也是至關地直觀, 就是構造一個新的對象,類型 是A

new 操做符構造了對象,並調用了 方法, 這個方法到底作了什麼呢? 也就是上面沒有分析的東東,看看先:

js 代碼
  1. var Class = {

  2. create: function() {

  3. returnfunction() { // 見[1]

  4. this.initialize.apply(this, arguments); // 見[2]

  5. }

  6. }

  7. }

[1]. new 操做符,就會在新產生的對象上調用這個方法
[2]. 哦? 這裏就是調用 this 對象上的 initialize方法, 並傳遞 arguments
換句話說,就是把構造的任務委託給 initialize 方法
initialize? 哪裏來? 見下面,類的擴展(繼承)

3. Prototype?

看段老代碼:

js 代碼
  1. var Person = function(name) {

  2. this.name = name;

  3. }

  4. var bencode = new Person("bencode");

bencode不是一個自閉的人,他應該能夠向javaeye介紹一下本身。
像這樣:

js 代碼
  1. bencode.sayHello();



假如不能實現以上功能的話, 上面的 new,上面全部的東東都等於垃圾。

因此。須要給 Person 類加"實例方法"

題外話: 靜態方法如何添加? 看上面的 Class.create, 僅僅是一個對象的成員而已

好, 再來一段 (爲了完整性,上面的幾句話,再抄一次)

js 代碼
  1. var Person = function(name) {

  2. this.name = name;

  3. }

  4. Person.prototype = { // protype 是啥?

  5. sayHello: function() {

  6. alert("hi, javaeye, I'm " + this.name);

  7. }

  8. }

  9. var bencode = new Person("bencode");

  10. bencode.sayHello();

運行代碼,經過!

prototype是啥? 請暫時忘記 Prototype(prototype.js) 這個庫,名字同樣而已!

讓咱們再從結果上去分析(第一次咱們用這種方法分析而得出了 new 的做用),

咱們在思考:
要想 bencode.sayHello() 正常運行
bencode 是一個對象, 這是咱們已經知道的
sayHello() 應該是 bencode 這個對象的方法才能夠

但是bencode 這個對象是 new 操做符產生的, 而 new 此時做用於 Person 這個 "類"
那麼, 哦? 那麼有兩種可能:
1. new 產生的那個新對象是否是就是 Person.prototype
2. Person.prototype 中的成員 將會被 new 操做符添加到 新產生的對象中

再看:

js 代碼
  1. Person.prototype = {

  2. sayHello: function() {

  3. alert("hi, javaeye, I'm " + this.name); // 這裏有this

  4. }

  5. }

this.name, 這裏的 this 指什麼?因此第一個可能講不通呀

回憶起這段:

js 代碼
  1. var Person = function(name) {

  2. this.name = name;

  3. }

若是這裏的 this 表明着新產生的對象的話。
那麼第二種狀況就講得通了, new 將會把 Person.prototype 這個對象的成員放到 這個新對象中。 與當前行爲相符。

因此: Person 的 Prototype 對象中的 成員, 將會被添加到 新產生的對象 中(我是這樣理解的)
(不知道 Js解釋器是否是開源的, 有空我得去看看,怎麼實現的。)

嘿,默認的 Prototype 就是 Object 哦!

4. 擴展?繼承?

什麼是擴展?啥是繼承? ! 我從爸爸那獲得了什麼?
想不通!

仍是實際點:

有一個類A, 它有一個 sayHello方法

js 代碼
  1. var A = function() {

  2. }

  3. A.prototype = {

  4. sayHello: function() {

  5. alert("sayHello A")

  6. }

  7. }

我想構造一個 B 類,讓他繼承 A 對象, 這句話太抽象。

其實咱們可能想這樣:

js 代碼
  1. var b = new B();

  2. b.sayHello(); // 調用 A 的 sayHello

這應該是繼承的第一層含義(重用)

怎麼辦到呢?

var B = function() { // 這裏是有一個B類了
}

怎麼樣添加"實例方法"? 快點想起 Prototype!!!

B.prototype = A.prototype

這樣行了嗎? 恭喜, 運行經過!

讓咱們整合一次

js 代碼
  1. var A = function() {

  2. }

  3. A.prototype = {

  4. sayHello: function() {

  5. alert("sayHello A");

  6. }

  7. }

  8. var B = function() {

  9. }

  10. B.prototype = A.prototype;

  11. var b = new B();

  12. b.sayHello();

但是若是 B 是這樣呢?

js 代碼
  1. var B = function() {

  2. }

  3. B.prototype = {

  4. sayHi: function() {

  5. alert("sayHi B");

  6. }

  7. }

咱們是否是應該將 A.prototype 中的內容添加到 B.prototype 對象中,而不是代替它呢? 固然。

這樣才能"擴展"

題外話?多態在哪裏? 嘿嘿

好了,足夠多了, 那prototype.js 是怎麼樣"擴展"的呢?

js 代碼
  1. Object.extend = function(destination, source) {

  2. for (var property in source) {

  3. destination[property] = source[property];

  4. }

  5. return destination;

  6. }

這個只是簡單地把 source 的成員, 添加到 destination 對象中嘛, 哪裏看得出擴展?

若是我這樣呢?

js 代碼
  1. var A = function() {

  2. }

  3. A.prototype = {

  4. sayHello: function() {

  5. alert("sayHello A")

  6. }

  7. }

  8. var B = function() {

  9. }

  10. Object.extend(B.prototype, A.prototype); // 先添加父類(A)成員

  11. Object.extend(B.prototype, { // 再添加B類成員, 若是是同名,則覆蓋,行爲符合 "多態"

  12. sayHi: function() {

  13. alert("sayHi B");

  14. }

  15. });

回憶剛纔的 Class.create():

js 代碼
  1. var Person = Class.create();

  2. var bencode = new Person("bencode");

剛纔說過, 調用 new 時, 將會建立一個新對象,而且調用 Person 方法, Person 方法會委託給 "新產生對象"的 initialize方法

怎麼樣給新產生對象添加 initialize 方法? 哈哈,輕鬆

js 代碼
  1. Object.extend(Person.prototype, {

  2. initialize: function() {

  3. this.name = name;

  4. } //,

  5. // 下面能夠添加其餘實例方法。

  6. });


因此, 咱們使用 Prototype 建立類通常格式是這樣的:

js 代碼
  1. var ClassName = Class.create();

  2. Object.extend(ClassName.prototype, {

  3. initialize: function(...) { // 這就至關於構造函數

  4. }

  5. //...

  6. });

若是咱們要繼承一個類,只要:

js 代碼
  1. var ClassName = Class.create();

  2. Object.extend(ClassName.prototype, SuperClassName.prototype);

  3. Object.extend(ClassName.prototype, {

  4. initialize: function(...) {

  5. }

  6. //...

  7. });

面向對象部分基本上就這樣。

但願對你們有點幫助!

原本想再接着寫 Prototype.js 的源碼解讀,但一來是由於時間,第二是發現也沒有這個必要。
這種東西是看起來快,寫起來慢的。哈哈!

原文網址

http://www.iteye.com/topic/57760

相關文章
相關標籤/搜索