基礎

this

在函數執行時,this 總是指向調用該函數的對象。要判斷 this 的指向,其實就是判斷 this 所在的函數屬于誰。

在《javaScript語言精粹》這本書中,把 this 出現的場景分為四類,簡單的說就是:

  • 有對象就指向調用對象
  • 沒調用對象就指向全局對象
  • 用new構造就指向新對象
  • 通過 apply 或 call 或 bind 來改變 this 的所指

繼承模式

圣杯模式實現

Father.prototype.lastname = "C";
Father.prototype.fortune = 1000000;
function Father() {
  this.age = 48;
}
function Son() {
  this.age = 18;
  this.waste = function() {
    return this.fortune - 50000;
  };
}
var inherit = (function() {
  //創建圣杯inherit函數
  /* 使用立即函數的原因:函數執行前會進行預編譯,預編譯過程都會產生AO,
如當前案例所示,案例中的立即執行函數(注:以下簡稱立函)執行前預編譯的AO中有buffer函數,
由于當立函執行完畢時會返回一個匿名函數(注:以下簡稱匿函),這個匿函調用了buffer函數,
最終匿函也被賦予到了inherit函數中,導致立函執行前預編譯產生的AO在立函執行完畢后并不會銷毀,
于是buffer函數成為了一個閉包并被一同賦予到了inherit函數中去了,
這樣當在外部使用inherit函數時,將會一直都在使用一個buffer函數,
而不用每次使用時都再新建一個buffer函數 */
  return function(targetSon, originFather) {
    //讓目標兒子繼承源頭父親
    function buffer() {} //buffer函數是一個閉包,僅用做一個緩沖而不做他用
    buffer.prototype = originFather.prototype;
    //targetSon.prototype = buffer.prototype; /* 不能這么寫,因為這樣寫就相當于對象targetSon、fatherOrigin和buffer共享原型了 */
    targetSon.prototype = new buffer(); /* 使對象targetSon試圖修改自身屬性時僅僅是以buffer函數作為對象進行修改,而不會影響到其他對象 */
    targetSon.prototype.constructor = targetSon; //令目標兒子記得自己本質是誰
    targetSon.prototype.gene = originFather; //令目標兒子記得自己的生父是誰
  };
})();
inherit(Son, Father); //調用圣杯inherit函數
Son.prototype.lastname = "X";
var son = new Son();
var father = new Father();
console.log(son.lastname); //控制臺顯示x,敗家兒子成功認賊作父
console.log(
  father.lastname
); /* 控制臺顯示c,父親自己的姓并沒有因為敗家兒子
                                 通過改姓來認賊作父的慘痛事實而改變 */
console.log(son.constructor); //控制臺顯示兒子自己的構造函數(本質)
console.log(son.gene); //控制臺顯示兒子自己的生父

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容