JavaScript 中的继承:如何调用对象父对象?

Inheritance in JavaScript: How can I call the object parent?

我正在 JavaScript 中构建一个多源音频播放器,我的目标是编写多个提供程序 classes(用于 Youtube、Soundcloud 等)以扩展基础 class,因此每个提供者都将具有相同的方法和属性,但我可以为每个提供者自定义它们。

这是一个简化的例子。

基础 class 看起来像这样:

function Player_Provider(slug) {
    this.slug = slug;
    console.log("Player_Provider init: " + this.slug);
};

Player_Provider.prototype.loadUrl = function(url) {
    console.log("provider "+this.slug+" - load URL: " + url);
};

我"extend"这个class对于提供者;例如:

function Player_Provider_Youtube() {
  Player_Provider.call(this, 'youtube');
}

Player_Provider_Youtube.prototype = Object.create(Player_Provider.prototype); //inherit methods
Player_Provider_Youtube.prototype.constructor = Player_Provider_Youtube; //fix constructor

Player_Provider_Youtube.prototype.loadUrl = function(url) {
    Player_Provider.prototype.loadUrl(url);
}

然后我这样注册:

var providers = [];
providers.youtube = new Player_Provider_Youtube();
providers.youtube.loadUrl("https://www.youtube.com/watch?v=5SIQPfeUTtg");

控制台输出:

Player_Provider init: youtube
provider undefined - load URL: https://www.youtube.com/watch?v=5SIQPfeUTtg

如你所见,控制台输出:

"provider undefined - load URL..."

当我希望它输出时:

"provider youtube - load URL..."

这里的想法是,在提供程序的每个函数中(每次都会覆盖基础 class 中的一个函数),我会首先调用 "parent" 函数,至少要输出像这里这样的控制台消息;并最终 运行 一些代码 - 本着拥有尽可能干净的代码的想法。

我对 PHP 更满意,这是我第一次尝试使用 JavaScript 来做那种事情。

你会怎么做,为什么我的变量未定义?

在 ES5 及更早版本中,这很痛苦。您使用 callapply,正如您所发现的,它真的很冗长。

Player_Provider_Youtube.prototype.loadUrl = function(url) {
    Player_Provider.prototype.loadUrl.call(this, url);
    // ------------------------------^^^^^^^^^^^
}

我发现我写了一个库来处理它(here),但它现在已经过时了。

但是,在2017年,你不会再这样做了;相反,您使用 ES2015 的 class 语法和转译(使用 Babel 之类的东西),因此它可以在较旧的 JavaScript 引擎上运行:

class Parent {
    method() {
        console.log("Parent method");
    }
}
class Child extends Parent {
    method() {
        console.log("Child method");
        super.method();
    }
}
new Child().method();

它会为您处理所有麻烦的管道。它仍然是 ES2015 之前的原型继承 + 构造函数,只是语法简单得多。 (并实现了一些旧语法无法做到的事情。)

我刚刚在做一个 JSFiddle,T.J.Crowder 打败了我!

function Player_Provider(slug) {
    this.slug = slug;
    console.log("Player_Provider init: " + this.slug);
};

Player_Provider.prototype.loadUrl = function(url) {
    console.log("provider "+this.slug+" - load URL: " + url);
};

function Player_Provider_Youtube() {
  Player_Provider.call(this, 'youtube');
}

Player_Provider_Youtube.prototype = Object.create(Player_Provider.prototype); //inherit methods
Player_Provider_Youtube.prototype.constructor = Player_Provider_Youtube; //fix constructor

Player_Provider_Youtube.prototype.loadUrl = function(url) {
    Player_Provider.prototype.loadUrl.call(this, url);
}

var providers = [];
providers.youtube = new Player_Provider_Youtube();
providers.youtube.loadUrl("https://www.youtube.com/watch?v=5SIQPfeUTtg");

https://jsfiddle.net/4Lmkuwts/