我有一个包含以下内容的文件:
rune
在另一个文件中,我可以像这样导入它:
var Foo = function() {};
Foo.prototype.bar = function() { return "hello world" }
export default function() {
return new Foo();
}
我需要一段时间才能完成这项工作。我感到困惑的具体事情是import Foo from "./my_other_file.js";
var foo = new Foo();
console.log(foo.bar());
// => "hello world"
。我最初的倾向是export default function() { return new Foo() }
(换句话说,返回类本身而不是实例)。
必须初始化类两次(导出时一次,导入后一次)似乎是多余的。这不是我第一次遇到这类事情 - 我在使用继承时也看到了它。
我的问题是 - 为什么会这样?这对我来说似乎不直观,所以我希望它有充分的理由。
答案 0 :(得分:2)
为什么会这样?
模块不直接导出Foo
构造函数,而只导出创建新Foo
实例的工厂函数。请注意,它不会导出实例本身(正如您的问题标题所示)。
这样做的好处是您可以省略new
关键字并执行
import Foo from "./my_other_file.js";
var foo = Foo(); // <==
console.log(foo.bar());
缺点当然是你不能轻易地对类进行子类化或扩展。
我最初的倾向是
return Foo
不,您不应导出返回类的函数(构造函数)。您应该使用export {Foo as default}
或
export default function Foo() {};
Foo.prototype.bar = function() { return "hello world" };
(当然,还是ES6中的export default class Foo {…}
)。
答案 1 :(得分:1)
我经常查看我将我的EMCAScript6类定义为类似C#Api中的类文件的文件。
在你的情况下,你要在Foo-Class文件中这样做,来定义你的类:
export default class Foo {
bar() {
return "hello world"
}
}
另一个文件保持不变。
这样您就不必创建该类的两个实例。您只需要创建使用它的实例。
如果您只是希望Foo文件返回一个返回&#34; hello world&#34;的函数,那么您可以这样做
export default function() {
return "hello world";
}
然后像其他函数一样在其他文件中使用Foo。
答案 2 :(得分:1)
上面的代码段预先假定有一个导入器(例如框架应用程序)需要工厂函数而不是构造函数:
import fooFactory from from "./my_other_file.js";
// launches a function and throws on constructors
fooConsumer(fooFactory);
任何方式,保持default
(作为手头的出口)和命名出口始终是个好主意。
export var Foo = function() {};
Foo.prototype.bar = function() { return "hello world" }
export default function() {
return new Foo();
}
即使现在没有在应用程序中使用已命名的导出,它们也可能在以后有用(用于测试)。