本文介紹
本文主要講解在JavaScript
中生命周期函數(shù)和鉤子函數(shù)的實(shí)現(xiàn),以及其原理借杰。
可以說(shuō)現(xiàn)在前端主流的框架都離不開(kāi)生命周期函數(shù)过吻,關(guān)于生命周期函數(shù)和鉤子函數(shù),之前我經(jīng)痴岷猓看到有人將它們混為一個(gè)概念纤虽。其實(shí)還是有點(diǎn)區(qū)別的乳绕,可以說(shuō)生命周期函數(shù)可能會(huì)包含著鉤子函數(shù),但也可能不包含逼纸,所以不是一個(gè)概念刷袍。下面例子會(huì)有助于你深刻理解這一理念。
其中JavaScript
中的生命周期函數(shù)的實(shí)現(xiàn)樊展,會(huì)跟其它語(yǔ)言有點(diǎn)不一樣呻纹,這個(gè)得靠自己體會(huì)了,本文只是一個(gè)牽引专缠。
說(shuō)到生命周期函數(shù)雷酪,其實(shí)還涉及到一種設(shè)計(jì)模式 - 模板方法模式,但是本文不討論涝婉,因?yàn)椴粫?huì)影響你對(duì)生命周期的理解哥力。
本文代碼風(fēng)格: ES5
內(nèi)容
生命周期
首先,來(lái)看下面代碼:
// 模擬一個(gè)動(dòng)物類
function Animal() {
}
// 由于每個(gè)動(dòng)物都會(huì)擁有該生命周期墩弯,所以寫(xiě)在prototype上
Animal.prototype = {
constructor: Animal,
// 假設(shè)這4步驟就是一個(gè)動(dòng)物生命中所經(jīng)歷的時(shí)期
step1: function() {
console.log('幼年');
},
step2: function() {
console.log('少年');
},
step3: function() {
console.log('中年');
},
step4: function() {
console.log('老年');
},
// 當(dāng)執(zhí)行該方法時(shí)吩跋,就讓生命周期按順序來(lái)進(jìn)行
init: function() {
this.step1();
this.step2();
this.step3();
this.step4();
}
}
// 創(chuàng)建動(dòng)物
var dog = new Animal();
// 開(kāi)啟生命篇章
dog.init();
控制臺(tái)打印如下:
但是,假如你是那種很有個(gè)性的人渔工,覺(jué)得用幼年锌钮、少年、中年引矩、老年
來(lái)形容自己太枯燥了梁丘,你想改寫(xiě)人生,重新繪制自己生命的藍(lán)圖旺韭,那也是可以的氛谜,方法如下:
// 創(chuàng)建屬于自己的人群
function ShaMaTe() {
}
// 繼承自Animal
ShaMaTe.prototype = new Animal();
// 指定構(gòu)造器,對(duì)原型鏈不了解的同學(xué)忽略這句即可
ShaMaTe.prototype.constructor = ShaMaTe;
// 重寫(xiě)方法
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()
// 開(kāi)啟人生
me.init()
你發(fā)現(xiàn)一個(gè)不一樣的人生区端,打印如下:
![控制臺(tái)打印]](http://upload-images.jianshu.io/upload_images/1486247-a2611126c669f227.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
好了值漫,生命周期函數(shù)講完了,這就是生命周期函數(shù):
- 按順序進(jìn)行
- 可以改寫(xiě)函數(shù)织盼,但函數(shù)還是按順序進(jìn)行
鉤子方法
看完生命周期函數(shù)的例子杨何,不知你有沒(méi)察覺(jué)到該例子的缺點(diǎn)沒(méi)有。那就是:在上面例子中悔政,如果一個(gè)動(dòng)物晚吞,假如它在幼年時(shí)期就死了延旧,但它還是會(huì)進(jìn)行后面的函數(shù)順序谋国。
因此在這里,我們要引入鉤子方法迁沫!
通過(guò)鉤子函數(shù)返回值芦瘾,來(lái)判斷捌蚊,來(lái)判斷人生還有沒(méi)必要再進(jìn)行下去:
// 拿第一份代碼中的Animal為例
Animal.prototype = {
// 省略代碼...
// 我們只需要對(duì)init方法進(jìn)行處理,其他保持不變
init: function() {
// 在這里近弟,我作一種假設(shè)缅糟,僅為舉例,具體的得按需求來(lái)
// 動(dòng)物在幼年時(shí)期是最容易死亡了,可能會(huì)被其它動(dòng)物吃掉
// 因此在幼年到少年期間祷愉,添加一個(gè)鉤子函數(shù),通過(guò)其返回值判斷是否繼續(xù)執(zhí)行
this.step1();
if (this.dieInBabyhood()) {
return
// 后面的不再執(zhí)行
}
this.step2();
this.step3();
this.step4();
},
// 然后給鉤子函數(shù)一個(gè)默認(rèn)返回值窗宦,默認(rèn)為false(不死)
this.dieInBabyhood: function () {
return false;
}
}
// 創(chuàng)建動(dòng)物對(duì)象
var dog = new Animal();
// 重寫(xiě)鉤子函數(shù)
dog.dieInBabyhood = function () {
return true;
}
// 開(kāi)啟生命周期
dog.init();
打印如下:可憐的小狗只走到了幼年
![控制臺(tái)打印]](http://upload-images.jianshu.io/upload_images/1486247-80925c080705c2d8.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
其實(shí)還有一種需求就是:在生命周期中,僅僅跳過(guò)了某時(shí)期二鳄,下面的依然還要進(jìn)行赴涵,這種需求實(shí)現(xiàn)如下:
Animal.prototype = {
// 省略代碼...
init: function() {
this.step1();
// 拿僅跳過(guò)step2為例
if (!this.isCrossStep2()) {
this.step2();
}
// 后面依然執(zhí)行
this.step3();
this.step4();
}
總結(jié)
- 生命周期函數(shù)包含鉤子函數(shù)
- 生命周期函數(shù)可以重寫(xiě)
- 通過(guò)重寫(xiě)鉤子函數(shù)可以決定是否進(jìn)行某一步操作