我正在用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来做这类事情。
你会怎么做?为什么我的变量未定义?
答案 0 :(得分:3)
在ES5及更早版本中,这是一种痛苦。您使用call
或apply
,正如您所发现的那样,它真的很冗长。
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");