JS 中的类
What are JavaScript Prototypes
JavaScript 中的ES2015类只是语法糖,它们并不真正存在。
添加类是为了让习惯于使用传统 OOP 方法处理类的程序员更容易处理继承。
当我们使用ES2015 类时,它只是在幕后使用原型系统——即使我们使用类语法,我们仍然在使用原型继承。
假设我们有以下课程:
class Employee { constructor(title) { this.title = title; } work() { console.log(`The ${this.title} is working.`); } }
真正运行的代码是以下构造函数:
function Employee(title) { this.title = title; } Employee.prototype.work = function () { console.log(`The ${this.title} is working.`); };
然后我们可以使用这个构造函数来初始化/使用我们希望 Employee 拥有的不同属性/方法:
const employee = new Employee('programmer'); employee.work();
原型属性
在构造函数内部,我们通常只关联我们希望对象拥有的属性,因为这些属性在我们创建的不同实例之间大多是唯一的。
当涉及到方法时——我们将它们放在prototype
对象上——因为实例之间的方法通常是相同的,并且在我们创建的每个实例上复制这些方法会浪费资源。
javascript语言中使用的解决方案是将方法委托给
prototype
对象。
如果你是我们上面创建console.log
的employee
实例,你会看到类似的东西:
{ title: 'programmer', __proto__: { work: () => {}, ... } }
所以我们看不到prototype
实例的属性,但我们看到了一个
__proto__
可以访问该work
方法的属性。
那么与 有什么__proto__
关系prototype
呢?
-
__proto__
是查找链中用于解析方法的实际对象。当我们尝试直接在实例上访问方法work
时
employee
——javascript 首先work
直接在实例上查找方法,当它找不到时——它适用于对象上的work
方法
。__proto__
-
prototype
是我们用关键字__proto__
创建对象时用来构建的对象。new
我们在对象上分配了work
方法
prototype
,然后使用该方法构建__proto__
实例,当未在实例上直接找到方法时,实例将使用该方法来查找方法。
这种委托方法的另一个好处是我们可以
prototype
在创建实例后将方法附加到类的对象,并且仍然在实例上使用该方法——因为 javascript 首先会在实例上查找方法,而当它没有时找不到它 – 它会在原型上查找。
function Employee(title) { this.title = title; } Employee.prototype.work = function () { console.log(`The ${this.title} is working.`); }; const employee = new Employee('programmer'); Employee.prototype.drinkCoffee = function () { console.log(`The ${this.title} drinks coffee`); }; // works employee.drinkCoffee();
我们可以回顾原型并添加、更新或删除方法,然后它们将反映在从该构造函数创建的所有实例之间。
摘要
当我们在 javascript 中使用类时——我们仍然使用prototype
系统,每个类都转换为一个构造函数,其原型存储了与该类关联的所有不同方法。