領(lǐng)悟 JavaScript 中的面向?qū)ο?/p>
注:讀完本文后請務(wù)必接著看完所有回復(fù)!
function func() {alert('Hello!');} alert(func.toString()); 在這個例子中,func 雖然是作為一個方法定義的,但它自身卻包含一個 toString 方法,說明 func 在這里是被當(dāng)成一個對象來處理的。更準(zhǔn)確的說,func 是一個“方法對象”。下面是例子的繼續(xù):
func.name = “I am func.”; alert(func.name); 我們可以任意的為 func 設(shè)置屬性,這更加證明了 func 就是一個對象。那么方法對象和普通對象的區(qū)別在哪里呢?首先方法對象當(dāng)然是可以執(zhí)行的,在它后面加上一對括號,就是執(zhí)行這個方法對象了。
func(); 所以,方法對象具有二重性。一方面它可以被執(zhí)行,另一方面它完全可以被當(dāng)成一個普通對象來使用。這意味著什么呢?這意味著方法對象是可以完全獨立于其他對象存在的。這一點我們可以同 Java 比較一下。在 Java 中,方法必須在某一個類中定義,而不能單獨存在。而 JavaScript 中就不需要。 方法對象獨立于其他方法,就意味著它能夠被任意的引用和傳遞。下面是一個例子:
function invoke(f) { f(); } invoke(func); 將一個方法對象 func 傳遞給另一個方法對象 invoke,讓后者在適當(dāng)?shù)臅r候執(zhí)行 func。這就是所謂的“回調(diào)”了。另外,方法對象的這種特殊性,也使得 this 關(guān)鍵字不容易把握。這方面相關(guān)文章不少,這里不贅述了。 除了可以被執(zhí)行以外,方法對象還有一個特殊的功用,就是它可以通過 new 關(guān)鍵字來創(chuàng)建普通對象。 話說每一個方法對象被創(chuàng)建時,都會自動的擁有一個叫 prototype 的屬性。這個屬性并無什么特別之處,它和其他的屬性一樣可以訪問,可以賦值。不過當(dāng)我們用 new 關(guān)鍵字來創(chuàng)建一個對象的時候,prototype 就起作用了:它的值(也是一個對象)所包含的所有屬性,都會被復(fù)制到新創(chuàng)建的那個對象上去。下面是一個例子:
func.prototype.name=”prototype of func”; var f = new func(); alert(f.name); 執(zhí)行的過程中會彈出兩個對話框,后一個對話框表示 f 這個新建的對象從 func.prototype 那里拷貝了 name 屬性。而前一個對話框則表示 func 被作為方法執(zhí)行了一遍。你可能會問了,為什么這個時候要還把 func 執(zhí)行一遍呢?其實這個時候執(zhí)行 func,就是起“構(gòu)造函數(shù)”的作用。為了形象的說明,我們重新來一遍:
function func() { this.name=”name has been changed.” } func.prototype.name=”prototype of func”; var f = new func(); alert(f.name); 你就會發(fā)現(xiàn) f 的 name 屬性不再是"prototype of func",而是被替換成了"name has been changed"。這就是 func 這個對象方法所起到的“構(gòu)造函數(shù)”的作用。所以,在 JavaScript 中,用 new 關(guān)鍵字創(chuàng)建對象是執(zhí)行了下面三個步驟的:
對于“new func()”這樣的語句,可以描述為“從 func 創(chuàng)建一個新對象”。總之,prototype 這個屬性的唯一特殊之處,就是在創(chuàng)建新對象的時候了。
A.prototype.hello = function(){alert('Hello!');} B.prototype = new A(); new B().hello(); 這就是 JavaScript 的所謂“繼承”了,其實質(zhì)就是屬性的拷貝,這里利用了 prototype 來實現(xiàn)。如果不用 prototype,那就用循環(huán)了,效果是一樣的。所謂“多重繼承”,自然就是到處拷貝了。 JavaScript 中面向?qū)ο蟮脑?,就是上面這些了。自始至終我都沒提到“類”的概念,因為 JavaScript 本來就沒有“類”這個東西。面向?qū)ο罂梢詻]有類嗎?當(dāng)然可以。先有類,然后再有對象,這本來就不合理,因為類本來是從對象中歸納出來的,先有對象再有類,這才合理。像下面這樣的:
|
|