个人简介
个人主页: 前端杂货铺
♂️学习方向: 主攻前端方向,正逐渐往全干发展
个人状态: 研发工程师,现效力于中国工业软件事业
人生格言: 积跬步至千里,积小流成江海
推荐学习:前端面试宝典 Vue2 Vue3 Vue2/3项目实战 Node.jsThree.js JS版算法
个人推广:每篇文章最下方都有加入方式,旨在交流学习&资源分享,快加入进来吧
大家好,这里是前端杂货铺。
前几天在公司做项目的时候发现了一个问题 => 在带 static 关键字的方法里面调用该类中的其他方法,其他方法也需要带 static 关键字。
举个简单的栗子:
class Person {
static toDo() {
this.say();
}
say() {
console.log('to say');
}
}
Person.toDo();
我相信,会有一部分小伙伴认为输出的结果是 to say
(和你一样,我一开始也这么认为),但实际的输出结果是:
是的,它报错了,它说 say 不是一个方法,这不胡扯吗?say 怎么可能不是一个方法?!
先别急,我们给 say 方法前面加上 static 关键字让其成为一个静态方法,再看看还会不会报错?
class Person {
static toDo() {
this.say();
}
static say() {
console.log('to say');
}
}
Person.toDo();
很神奇,加上 static 它就不报错了…
在了解 static 施了什么魔法之前我们先认识一下 static 吧。
在 MDN 上是这样定义static 的:
关键字 static 将为一个类定义一个静态方法。静态方法不是在一个实例之上被调用,而是在类自身之上被调用。它们通常是工具函数,比如用来创建或者复制对象。
(注:“工具函数” 就是指具有某些功能的函数,这些函数(或者叫做方法)就像工具一样,当我们需要它们的时候,就可以使用它们)
我们简单认识了 static 的定义和用途,那么接下来我们来分析一下为什么在方法前加上 static 关键字就不报错呢?
生命周期不同:
静态方法属于类。 静态方法的生命周期跟相应的类一样长,静态方法和静态变量会随着类的定义而被分配和装载入内存中。一直到线程结束,静态属性和方法才被销毁。
非静态方法属于对象。 非静态方法的生命周期和类的实例化对象一样长,只有当类实例化了一个对象,非静态方法才会被创建,而当这个对象被销毁时,非静态方法也马上被销毁。
所以,当对象不存在时非静态方法也不存在,静态方法自然也就不能调用一个不存在(非静态)的方法。
现在我们知道了 静态方法不能调用非静态方法,那么非静态方法可以调用静态方法吗?经过我们上述的分析,答案是肯定的!
class Person {
toDo() {
Person.say();
}
static say() {
console.log('to say');
}
}
let person = new Person();
person.toDo();
尺有所短寸有所长,static 当然也不是完美的…
static的优点:
- 属于类级别的,不需要创建对象就可以直接使用
- 全局唯一,内存唯一,静态变量可以唯一标识某些状态
- 在类加载时候初始化,常驻在内存中,调用快捷方便
static的缺点:
- 静态方法不能调用非静态的方法和变量.(非静态方法可以任意的调用静态方法/变量)
- 不能使用this和super关键字(属于类级别,没有创建对象前不可用this/super)
应用场景:
- 静态方法最适合工具类中方法的定义;比如文件操作,日期处理方法等.
- 静态方法适合入口方法的定义;如单例模式,因为从外部拿不到构造函数,所以定义一个静态的方法获取对象非常有必要.
- 静态变量适合全局变量的定义.(如布尔型静态成员变量做控制符)
本篇文章我们探讨了静态方法。
静态方法属于类级别的,而非静态方法属于对象级别的。通过对 生命周期 的分析,我们理解了静态方法中不能调用非静态方法,而非静态方法中可以调用静态方法的原因。
之后我们对 static 的优缺点进行了列举,对其应用场景有了一定的认识。
好啦,本篇文章到这里就要和大家说再见啦,祝你这篇文章阅读愉快,你下篇文章的阅读愉快留着我下篇文章再祝!
参考资料:
- MDN 官方文档
- JavaScript 静态方法 【作者:三季人 G】
- 百度百科 · 屈原《卜居》