生命周期函數與鉤子函數 - 詳解

本文介紹

本文主要講解在JavaScript中生命周期函數和鉤子函數的實現,以及其原理。

可以說現在前端主流的框架都離不開生命周期函數,關于生命周期函數鉤子函數,之前我經常看到有人將它們混為一個概念。其實還是有點區別的,可以說生命周期函數可能會包含著鉤子函數,但也可能不包含,所以不是一個概念。下面例子會有助于你深刻理解這一理念。

其中JavaScript中的生命周期函數的實現,會跟其它語言有點不一樣,這個得靠自己體會了,本文只是一個牽引。

說到生命周期函數,其實還涉及到一種設計模式 - 模板方法模式,但是本文不討論,因為不會影響你對生命周期的理解。

本文代碼風格: ES5

內容

生命周期

首先,來看下面代碼:

// 模擬一個動物類
function Animal() {

}

// 由于每個動物都會擁有該生命周期,所以寫在prototype上
Animal.prototype = {
  constructor: Animal,
  // 假設這4步驟就是一個動物生命中所經歷的時期
  step1: function() {
    console.log('幼年');
  },
  step2: function() {
    console.log('少年');
  },
  step3: function() {
    console.log('中年');
  },
  step4: function() {
    console.log('老年');
  },
  // 當執行該方法時,就讓生命周期按順序來進行
  init: function() {
    this.step1();
    this.step2();
    this.step3();
    this.step4();
  }
}
// 創建動物
var dog = new Animal();
// 開啟生命篇章
dog.init();

控制臺打印如下:

控制臺打印

但是,假如你是那種很有個性的人,覺得用幼年、少年、中年、老年來形容自己太枯燥了,你想改寫人生,重新繪制自己生命的藍圖,那也是可以的,方法如下:

// 創建屬于自己的人群
function ShaMaTe() {
    
}
// 繼承自Animal
ShaMaTe.prototype = new Animal();
// 指定構造器,對原型鏈不了解的同學忽略這句即可
ShaMaTe.prototype.constructor = ShaMaTe;
// 重寫方法
ShaMaTe.prototype.step1 = function() {
  console.log('*﹏拗哖〆…');
}
ShaMaTe.prototype.step2 = function() {
  console.log('尐哖');
}
ShaMaTe.prototype.step3 = function() {
  console.log('筗哖');
}
ShaMaTe.prototype.step4 = function() {
  console.log('荖哖');
}

var me = new ShaMaTe()
// 開啟人生
me.init()

你發現一個不一樣的人生,打印如下:

![控制臺打印]](http://upload-images.jianshu.io/upload_images/1486247-a2611126c669f227.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

好了,生命周期函數講完了,這就是生命周期函數:

  1. 按順序進行
  2. 可以改寫函數,但函數還是按順序進行

鉤子方法

看完生命周期函數的例子,不知你有沒察覺到該例子的缺點沒有。那就是:在上面例子中,如果一個動物,假如它在幼年時期就死了,但它還是會進行后面的函數順序。

因此在這里,我們要引入鉤子方法

通過鉤子函數返回值,來判斷,來判斷人生還有沒必要再進行下去:

// 拿第一份代碼中的Animal為例
Animal.prototype = {
  // 省略代碼...
  
  // 我們只需要對init方法進行處理,其他保持不變
  init: function() {
    // 在這里,我作一種假設,僅為舉例,具體的得按需求來
    // 動物在幼年時期是最容易死亡了,可能會被其它動物吃掉
    // 因此在幼年到少年期間,添加一個鉤子函數,通過其返回值判斷是否繼續執行
    this.step1();
    if (this.dieInBabyhood()) {
        return
        // 后面的不再執行
    }
    this.step2();
    this.step3();
    this.step4();
  },
  // 然后給鉤子函數一個默認返回值,默認為false(不死)
  this.dieInBabyhood: function () {
    return false;
  }
}

// 創建動物對象
var dog = new Animal();
// 重寫鉤子函數
dog.dieInBabyhood = function () {
    return true;
}
// 開啟生命周期
dog.init();

打印如下:可憐的小狗只走到了幼年

![控制臺打印]](http://upload-images.jianshu.io/upload_images/1486247-80925c080705c2d8.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

其實還有一種需求就是:在生命周期中,僅僅跳過了某時期,下面的依然還要進行,這種需求實現如下:

Animal.prototype = {
  // 省略代碼...
  
  init: function() {
    this.step1();
    // 拿僅跳過step2為例
    if (!this.isCrossStep2()) {
      this.step2();
    }
    // 后面依然執行
    this.step3();
    this.step4();
  }

總結

  1. 生命周期函數包含鉤子函數
  2. 生命周期函數可以重寫
  3. 通過重寫鉤子函數可以決定是否進行某一步操作
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,455評論 25 708
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,973評論 19 139
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,767評論 18 399
  • Vue 實例中的生命周期鉤子 本博客版權歸本人和饑人谷所有,轉載需說明來源Vue 框架的入口就是 Vue 實例,其...
    饑人谷_小k閱讀 2,508評論 2 7
  • 天亮了,當第一縷陽光灑在床邊, 當揉著睡意朦朧眼睛。 一時間也沒有想傷悲,沐浴在和煦的暖陽里。 時間不能倒流,所有...
    葉夕云閱讀 1,089評論 3 4