深入理解javascript原型和閉包(3)——prototype原型

王福朋發表於2014-09-17

既typeof之後的另一位老朋友!

prototype也是我們的老朋友,即使不瞭解的人,也應該都聽過它的大名。如果它還是您的新朋友,我估計您也是javascript的新朋友。

 

在我們們的第一節(深入理解javascript原型和閉包(1)——一切都是物件)中說道,函式也是一種物件。他也是屬性的集合,你也可以對函式進行自定義屬性。

不用等我們們去試驗,javascript自己就先做了表率,人家就預設的給函式一個屬性——prototype。對,每個函式都有一個屬性叫做prototype。

這個prototype的屬性值是一個物件(屬性的集合,再次強調!),預設的只有一個叫做constructor的屬性,指向這個函式本身。

如上圖,SuperType是是一個函式,右側的方框就是它的原型。

原型既然作為物件,屬性的集合,不可能就只弄個constructor來玩玩,肯定可以自定義的增加許多屬性。例如這位Object大哥,人家的prototype裡面,就有好幾個其他屬性。

咦,有些方法怎麼似曾相似?

對!彆著急,之後會讓你知道他們為何似曾相識。

接著往下說,你也可以在自己自定義的方法的prototype中新增自己的屬性

        function Fn() { }
        Fn.prototype.name = '王福朋';
        Fn.prototype.getYear = function () {
            return 1988;
        };

看到沒有,這樣就變成了

沒問題!

但是,這樣做有何用呢? —— 解決這個問題,我們們還是先說說jQuery吧。

var $div = $('div');
$div.attr('myName', '王福朋');

以上程式碼中,$('div')返回的是一個物件,物件——被函式建立的。假設建立這一物件的函式是 myjQuery。它其實是這樣實現的。

        myjQuery.prototype.attr = function () {
            //……
        };
        $('div') = new myjQuery();

不知道大家有沒有看明白。

如果用我們們自己的程式碼來演示,就是這樣

        function Fn() { }
        Fn.prototype.name = '王福朋';
        Fn.prototype.getYear = function () {
            return 1988;
        };

        var fn = new Fn();
        console.log(fn.name);
        console.log(fn.getYear());

即,Fn是一個函式,fn物件是從Fn函式new出來的,這樣fn物件就可以呼叫Fn.prototype中的屬性。

因為每個物件都有一個隱藏的屬性——“__proto__”,這個屬性引用了建立這個物件的函式的prototype。即:fn.__proto__ === Fn.prototype

這裡的"__proto__"成為“隱式原型”,下回繼續分解。

 

---------------------------------------------------------------------------

本文已更新到《深入理解javascript原型和閉包》的目錄,更多內容可參見《深入理解javascript原型和閉包》。

另外,歡迎關注我的微博

學習作者教程:《前端JS高階面試》《前端JS基礎面試題》《React.js模擬大眾點評webapp》《zepto設計與原始碼分析》《json2.js原始碼解讀

相關文章