动态

详情 返回 返回

從JQuery出發總結的關於原型使用上的一些淺薄理解 - 动态 详情

比如我們現在的需求如下。

有一個函數MyObj,支持如下功能:

  • 可以通過MyObj()的方式返回一個對象,這個對象和new MyObj()是等價的
  • MyObj本身是一個對象,可以通過MyObj.doit()的方式調用其上的方法或屬性
    為了實現需求,第一反應是:

    var MyObj=function(){
      return new MyObj();
    };

    然後在MyObj上掛載靜態方法,在MyObj.prototype上掛載對象方法。

看起來穩的很,其實這明顯是一個死循環:

// VM160:2 Uncaught RangeError: Maximum call stack size exceeded
MyObj();

為了解決這個問題,我們在MyObj的原型上定義了一個方法:

MyObj.prototype.init=function(){
    return this;
};

執行下面的方法:

var temp=MyObj.prototype.init();

上面返回的temp很明顯就是MyObj.prototype,其實就是MyObj對象(例如:new A(),其實就是取A.prototype,這樣對比就很好理解了)。

因此可以改造代碼如下:

var MyObj = function (param) {
    return MyObj.prototype.init();
};

這樣MyObj和new MyObj()就分別表示類和對象。

問:看起來是不是實現了?
答:是的,實現了。
問:可是總感覺有點不好,説不出為什麼。
答:是不是感覺MyObj()打印出來的東西有點多?
問:是的。

事實上,因為直接取MyObj.prototype作為new MyObj(),理論上説,使用上區別不大,唯一不足的是,掛載在MyObj.prototype上的方法會在打印MyObj對象的時候看見,不舒服。

為了看起來好看些,代碼再次改造:

var MyObj = function () {
    return new MyObj.prototype.init();
};

// 為了讓MyObj()返回的是MyObj對象,需要修改MyObj.prototype.init的原型
MyObj.prototype.init.prototype = MyObj.prototype;

此刻的原型關係變成了:

MyObj() ==
return new MyObj.prototype.init() ==
MyObj.prototype.init.prototype ==
MyObj.prototype ==
new MyObj()

此時需求就實現了,而且打印MyObj()的時候,對象上的方法都在原型上,看起來就比較舒服了。

user avatar Leesz 头像 alibabawenyujishu 头像 haoqidewukong 头像 zaotalk 头像 smalike 头像 linlinma 头像 yinzhixiaxue 头像 littlelyon 头像 zourongle 头像 linx 头像 anchen_5c17815319fb5 头像 u_17443142 头像
点赞 111 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.