在 JavaScript 中,ES6 开始引入class
的概念。实际上,JavaScript 中class
的本质也是基于原型prototype
的实现方式作了进一步的封装,其本质还是函数function
。虽说如此,class
和function
还是有不同之处。
1. 相同点:都可作为构造函数
1. 函数作为构造函数
class
和function
都可以作为构造函数,通过new
操作符来实例化。
如下代码,函数作为构造函数的写法。函数作为构造函数,通常首字母要大写。构造函数中的this
指向构造函数创建出来的实例对象usr
。
function Person(name) {
this.name = name;
}
const usr = new Person('Jack');
console.log(usr); // Person { name: 'Jack' }
2. 类实现构造函数
类可以包含构造函数方法、实例方法、setter
函数、getter
函数和静态类方法,但这些都不是必须的。
如下代码所示,定义一个class
,需要用class
关键字加上类名,类名建议首字母大写。类中的constructor
方法是一个特殊的方法,称为构造函数方法,用来初始化一个对象,在一个class
中,只能有一个constructor
方法,若定义多个constructor
将会报错。
在用new
操作符创建类的实例时,会自动调用这个constructor
函数。若不定义constructor
,相当于constructor
为空函数。
class Person {
constructor(name) {
this.name = name;
}
}
const usr = new Person('Jack');
console.log(usr); // Person { name: 'Jack' }
类实例化时,传入的参数会用作构造函数的参数,如果没有参数传递,则类名后面的括号可以省略:
class Person {
constructor() {
this.name = 'Jack';
}
}
const usr = new Person;
console.log(usr); // Person { name: 'Jack' }
2. 不同点
1. class构造函数必须使用new操作符
class
构造函数与function
构造函数的主要区别为,调用class
构造函数必须使用new
操作符。而普通function
构造函数如果不使用new
调用,那么会以全局的this
(在浏览器中是window
)作为内部对象。
如下代码,普通function
构造函数把window
作为this
来创建实例:
function Person() {}
const p = Person();
调用class
构造函数时如果忘了使用new
则会抛出错误:
class Animal {}
const a = Animal();
// TypeError: Class constructor Animal cannot be invoked without 'new'
2. class声明不可以提升
function
构造函数声明存在提升,也就是定义构造函数的部分可以写在实例化对象的后面:
const usr = new Person('Jack');
console.log(usr); // Person { name: 'Jack' }
function Person(name) {
this.name = name;
}
class
声明不存在提升,声明类的部分不能写在实例化对象的后面,如下代码所示,报错信息显示Cannot access 'Person' before initialization
。
const usr = new Person('Jack');
// ReferenceError: Cannot access 'Person' before initialization
class Person {
constructor(name) {
this.name = name;
}
}
3. class不可以用call、apply、bind改变执行上下文
普通的function
函数,调用时可以使用call
、apply
、bind
改变其this
指向,如下代码,调用sayName
的同时,通过call
改变其this
指向为obj
,打印出了obj
对象中的name
属性。
function sayName() {
console.log(this.name);
}
const obj = {
name: 'Jack',
};
sayName.call(obj); // Jack
call
、apply
、bind
具体使用方式见「JavaScript call()、apply()、bind()的区别」。
若class
也尝试用call
改变其this
指向时会报错:
class Person {
constructor() {
this.name = 'Tom';
}
}
const obj = {
name: 'Jack',
};
Person.call(obj); // TypeError: Class constructor Person cannot be invoked without 'new'
参考:
📘📘欢迎在我的博客上访问:
https://lzxjack.top/