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

时间:2017-04-20 15:15:10

标签: javascript object inheritance prototypal-inheritance

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

这是一个简化的例子。

基类如下所示:

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(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

如您所见,控制台输出:

  

"提供商未定义 - 加载网址..."

当我希望输出时:

  

"提供商 youtube - 加载网址..."

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

我更熟悉PHP,这是我第一次尝试使用JavaScript来做这类事情。

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

2 个答案:

答案 0 :(得分:3)

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

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

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

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



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




为你处理所有令人讨厌的管道。它在ES2015之前的仍然是相同的原型继承+构造函数,它的语法更为简单。 (并支持我们无法处理旧语法的一些事情。)

答案 1 :(得分:-1)

我只是在做一个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/