本文介绍
本文主要讲解在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()
你发现一个不一样的人生,打印如下:
好了,生命周期函数讲完了,这就是生命周期函数:
- 按顺序进行
- 可以改写函数,但函数还是按顺序进行
钩子方法
看完生命周期函数的例子,不知你有没察觉到该例子的缺点没有。那就是:在上面例子中,如果一个动物,假如它在幼年时期就死了,但它还是会进行后面的函数顺序。
因此在这里,我们要引入钩子方法!
通过钩子函数返回值,来判断,来判断人生还有没必要再进行下去:
// 拿第一份代码中的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();
打印如下:可怜的小狗只走到了幼年
其实还有一种需求就是:在生命周期中,仅仅跳过了某时期,下面的依然还要进行,这种需求实现如下:
Animal.prototype = {
// 省略代码...
init: function() {
this.step1();
// 拿仅跳过step2为例
if (!this.isCrossStep2()) {
this.step2();
}
// 后面依然执行
this.step3();
this.step4();
}
总结
- 生命周期函数包含钩子函数
- 生命周期函数可以重写
- 通过重写钩子函数可以决定是否进行某一步操作