簡體   English   中英

什么是原型繼承中call()的需要

[英]What's the need for call() in prototypical inheritance

我在解析JavaScript中的原型繼承時遇到了一些麻煩,並考慮在此處發布。 考慮這個簡單的例子:

function Employee() {
    this.name = "Rob";
    this.dept = "R&D";
}

function Manager() {
    //Employee.call(this);
    this.reports = ["Report 1", "Report 2", "Report 3"];
}

Manager.prototype = Object.create(Employee.prototype);

Employee.prototype.type = "human";
m = new Manager();
console.log(m.name); //undefined
console.log(m.type); //human

我無法理解的是Employee.call(this)這一行的效用。 既然我們要將Employee.protoype設置為Manager的原型,那么(我看到它)通過call()明確強制在Employee中創建變量的需求是什么? 之前我認為可能是因為沒有Employee對象存在,並且JS繼承在沒有對象的情況下無法工作,所以call()在這里用於“完成對象構建”。 但是, type屬性在Manager中反映出來而不需要call() ,這證明我們不需要硬對象來執行繼承(我的意思是,只是類類構造函數定義會這樣做)。

我希望我沒有把它變得太復雜。 簡而言之:為什么這里需要call() ,為什么屬性type在沒有call()情況下工作(如果call()很重要,那就是)。

Employee.call(this)的目的是向Manager實例添加名稱和部門屬性。

call()的使用更符合慣例,它允許修改調用者(this)。

您通過原型界面后,屬性type工作。

如果取消注釋Employee.call(this) ,則m.name將變為“Rob”。

即使原型是繼承的,也就是定義了'human'類型的地方,而沒有調用Employee,你不是“初始化基類”並在Employee()構造函數中運行代碼。 僅僅因為Employee是Manager的原型並不保證您在創建管理器時想要運行Employee構造函數。

與某些可以調用super()語言不同,您必須按名稱調用基類的初始化程序。 這類似於C ++:

class Manager : public Employee {
public:
    Manager() : Employee() {}
};

您還可以決定何時調用父項並執行其他邏輯,其中自動調用不會為您提供該選項:

function Employee(name) {
    this.name = name;
    this.dept = "R&D";
}

function Manager(name) {
    // Add the title to the name, first
    var mgrName = name + ' (Manager)';

    Employee.call(this, mgrName);
    this.reports = ["Report 1", "Report 2", "Report 3"];
}

Manager.prototype = Object.create(Employee.prototype);
m = new Manager('Bill');

.type (和其他原型繼承的屬性)確實有效。
.name.dept沒有,它們不是在m創建的! 你是對的, Employee.call(this)完整初始化所必需的。 這是構造函數的super調用,你不應該忽略它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM