假设我有一个 Ruby 类和一个 Ruby 模块
module Foo
def hello
puts 'hello'
end
end
class Bar
include Foo
end
现在我可以做这样的事情
Bar.new.hello
我可以在 JavaScript 中做同样的事情吗?我不能使用extends
关键字,因为我的 JavaScript 类已经被继承。如何将一些功能混合到我的课程中?
更新
我想使用与 ES6 类一起使用的东西
假设我有一个 Ruby 类和一个 Ruby 模块
module Foo
def hello
puts 'hello'
end
end
class Bar
include Foo
end
现在我可以做这样的事情
Bar.new.hello
我可以在 JavaScript 中做同样的事情吗?我不能使用extends
关键字,因为我的 JavaScript 类已经被继承。如何将一些功能混合到我的课程中?
更新
我想使用与 ES6 类一起使用的东西
Javascript 语言中没有任何东西直接支持这一点,但它可以被模拟。
var Foo = {
hello: function() {
console.log("hello");
}
};
function Bar() {}
for (var key in Foo) {
Bar.prototype[key] = Foo[key];
}
new Bar().hello(); // prints hello
这将遍历所有内容Foo
并将其添加到Bar
.
您可以使用原型继承。
var Foo = function(){
this.hello = function(){
console.log('hello');
}
}
var Bar = function(){
Foo.call(this);
}
Bar.prototype = Object.create(Bar);
new Bar().hello();
我确实建议阅读我在 SO 上给出的一些列出的答案,这些答案与 OP 的答案非常相关。
...编辑:顺便说一句,搜索“es6 classes mixins”确实已经指向ES6 classes 的 Mixins,用 babel 转译...
使用 OP 的例子,一个已经可靠的答案可能会被简单地分解为......
function withSayHello() { // - function based *Flight Mixin* as of Angus Croll.
this.sayHello = function () { // - should be encouraged becoming the main approach
// (though featuring a sugared syntax) of a future
console.log(this.hello); // *Lightweight Trait* implementation.
}; //
} //
function Bar() { // - classic ES3 constructor.
this.hello = 'hello'; //
//
withSayHello.call(this); // - applying the function based Mixin/Trait/Talent
} // from above.
var bar = new Bar;
bar.sayHello();
class Foo { // - with syntactic "class" sugar ...
constructor() { // ... `constructor` does remain the place for ...
this.hello = 'Howdy!'; //
//
withSayHello.call(this); // ... applying function based Mixins/Traits/Talents.
} //
} //
var foo = new Foo;
foo.sayHello();
也可以使用Babel 的 REPL检查上述示例。
浏览器仍然不支持 JavaScript 的标准化模块系统。另一方面,例如 JS 库和 NodeJS 环境确实提供了它们自己的模块系统。上面的工作示例很容易在每个示例中传输/转译 - 但这里再次进入标准示例,因为它已经受到Babel和Traceur等编译器的支持。
// module "my_special_withSayHello_mixin.js"
//
export default function withSayHello() {
this.sayHello = function () {
console.log(this.hello);
};
}
// module "my_very_own_Foo_implementation.js"
//
import withSayHello from 'my_special_withSayHello_mixin';
export default class Foo {
constructor() {
this.hello = 'Howdy!';
withSayHello.call(this);
}
}
// module "main.js"
//
import Foo from 'my_very_own_Foo_implementation';
var foo = new Foo;
foo.sayHello();