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 及更早版本中,这很痛苦。您使用 call
或 apply
,正如您所发现的,它真的很冗长。
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");
我正在 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 及更早版本中,这很痛苦。您使用 call
或 apply
,正如您所发现的,它真的很冗长。
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");