在JavaScript中,class和构造函数是两种常见的创建对象的方式。虽然class在ES6中被引入,但它背后仍然基于构造函数的原理。然而,class和构造函数在语法和行为上存在一些重要的区别。
一、回顾class的写法
ES6引入了class语法,使得创建类更加直观和简洁。以下是一个简单的class示例:
class Computer {
constructor(name, price) {
this.name = name;
this.price = price;
}
showSth() {
console.log(`这是一台${this.name}电脑`);
}
static comStruct() {
console.log("电脑由显示器,主机,键鼠组成");
}
}
var apple = new Computer("苹果", 15000);
console.log(apple.name); // 苹果
console.log(apple.price); // 15000
apple.showSth(); // 这是一台苹果电脑
Computer.comStruct(); // 电脑由显示器,主机,键鼠组成
在上面的代码中,我们定义了一个名为Computer的类,该类包含实例属性name和price,一个原型方法showSth以及一个静态方法comStruct。
二、回顾构造函数的写法
在ES6出现之前,我们通常使用构造函数来模拟类。以下是一个等效的ES5写法:
function Computer(name, price) {
this.name = name;
this.price = price;
}
Computer.prototype.showSth = function() {
console.log(`这是一台${this.name}电脑`);
};
Computer.comStruct = function() {
console.log("电脑由显示器,主机,键鼠组成");
};
var apple = new Computer("苹果", 15000);
console.log(apple.name); // 苹果
console.log(apple.price); // 15000
apple.showSth(); // 这是一台苹果电脑
Computer.comStruct(); // 电脑由显示器,主机,键鼠组成
在上面的代码中,我们通过构造函数Computer来创建对象,并将方法挂在原型上。
三、class和构造函数的区别
(一)调用方式
构造函数可以通过普通函数调用,而class必须通过new关键字调用。
function Computer2(name, price) {
this.name = name;
this.price = price;
}
var i = Computer2(); // 不会报错,返回undefined
console.log(i); // undefined
class Computer1 {
constructor(name, price) {
this.name = name;
this.price = price;
}
}
var i = Computer1(); // 报错
// TypeError: Class constructor Computer1 cannot be invoked without 'new'
(二)枚举性
ES6中的class方法默认是不可枚举的,而ES5中的原型方法是可枚举的。
var apple = new Computer2("苹果", 15000);
for (var i in apple) {
console.log(i); // name, price, showSth
}
var huawei = new Computer1("华为", 12000);
for (var i in huawei) {
console.log(i); // name, price
}
(三)严格模式
ES6的class内部默认是严格模式,而ES5的构造函数不是。
class Computer1 {
showSth(i, i) { // 报错
console.log(`这是一台${this.name}电脑`);
}
}
function Computer2(name, price) {
this.name = name;
this.price = price;
}
Computer2.prototype.showSth = function(i, i) { // 不会报错
console.log(`这是一台${this.name}电脑`);
};
(四)原型方法的调用
ES6的class原型方法不能通过new调用,而ES5的原型方法可以。
var apple = new Computer2("苹果", 15000);
var i = new apple.showSth(); // 不会报错,返回一个空对象
console.log(i); // {}
var huawei = new Computer1("华为", 12000);
var i = new huawei.showSth(); // 报错
// TypeError: huawei.showSth is not a constructor