原文地址:https://dev.to/bhagatparwinder/classes-not-just-syntactic-sugar-1n0m
上篇文章我们提到了类以及它是如何根据模板更简单的创建对象。class
关键字是在 ES2015/ES6 中引入的,有个常见的误区类只是语法糖仅此而已。类是面向对象编程的基础,我的这篇文章的目的是阐明这个误区和展示与通过 new
关键字创建对象的细微差别。
类都做了什么?
class EmployeeRecord {
name = "New User";
id = 0;
constructor(firstName, lastName, id) {
this.name = `${firstName} ${lastName}`;
this.id = id;
}
reverseName() {
return this.name.split("").reverse().join("");
}
}
const employee1 = new EmployeeRecord("Parwinder", "Bhagat", 1);
const employee2 = new EmployeeRecord("Lauren", "L", 2);
console.log(employee1.name); // Parwinder Bhagat
console.log(employee2.name); // Lauren L
console.log(employee1.reverseName()); // tagahB redniwraP
在上面的 class
例子中:
- 在底层,创建了一个名为
EmployeeRecord
的函数,函数体就是由类的构造函数组成。如果没有构造函数,函数体将是空的。 - 类中所有的函数都会被存储在
EmployeeRecord
的原型上。
根据上面的逻辑,我们可以不用 class
关键字来重写上面的例子。
function EmployeeRecord(firstName, lastName, id) {
this.name = `${firstName} ${lastName}`;
this.id = id;
}
EmployeeRecord.prototype.reverseName = function () {
return this.name.split("").reverse().join("");
}
let employee1 = new EmployeeRecord("Parwinder", "Bhagat", 1);
const employee2 = new EmployeeRecord("Lauren", "L", 2);
console.log(employee1.name); // Parwinder Bhagat
console.log(employee2.name); // Lauren L
console.log(employee1.reverseName()); // tagahB redniwraP
类有何不同?
- 有一个特定的函数种类分配给类,并且在多个地方被检查,最重要的是当我们实例化一个类时。
class EmployeeRecord {
constructor() { }
}
console.log(typeof EmployeeRecord); // function
EmployeeRecord(); // Value of type 'typeof EmployeeRecord' is not callable. Did you mean to include 'new'?
- 构造函数式的继承依赖原型链,而类则是通过
extends
关键字。
class Person {
sayName() {
console.log("My name is Person");
}
sayAge() {
console.log("I am 30 years old."); // I am 30 years old.
}
}
class Employee extends Person {
sayDepartment() {
console.log("I work for the tech department."); // I work for the tech department.
}
sayHello() {
console.log("Hi, I am the new employee"); // Hi, I am the new employee
}
}
let employee = new Employee;
employee.sayHello();
employee.sayAge();
employee.sayDepartment();
console.log(employee instanceof Person); // true
console.log(employee instanceof Employee); // true
- 函数声明是会被提升,而类的声明不会。
const employee = new Employee(); // ReferenceError or Employee is not a constructor
class Employee {
constructor() {}
}
- 类始终运行在严格模式下,类中的所有代码自动都在严格模式下。
- 函数声明或表达式可以被覆盖就像
var
声明的变量而类则不行。类就像let
和const
关键字声明的变量,let 在同一个作用域中是不允许声明同名变量的。 - 对象的不可枚举属性在迭代的时候不会出现,类中的方法不会被迭代到。若我们使用
for...in
来遍历类中的对象,不会有方法出现。