Javascript ES6导出默认值,多个功能相互引用
在es6中,您可以定义这样的函数模块Javascript ES6导出默认值,多个功能相互引用,javascript,ecmascript-6,Javascript,Ecmascript 6,在es6中,您可以定义这样的函数模块 export default { foo() { console.log('foo') }, bar() { console.log('bar') }, baz() { foo(); bar() } } 上面的代码似乎有效,但如果我调用baz()它会抛出一个错误: ReferenceError:未定义foo 如何从另一个函数调用foo?在这种情况下,baz 编辑 这是实际上不起作用的代码。我简化了代码,因此它只是需要的核心 con
export default {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { foo(); bar() }
}
上面的代码似乎有效,但如果我调用baz()
它会抛出一个错误:
ReferenceError:未定义foo
如何从另一个函数调用foo
?在这种情况下,baz
编辑
这是实际上不起作用的代码。我简化了代码,因此它只是需要的核心
const tokenManager = {
revokeToken(headers) {
...
},
expireToken(headers) {
...
},
verifyToken(req, res, next) {
jwt.verify(... => {
if (err) {
expireToken(req.headers)
}
})
}
}
export default tokenManager
错误是
expireToken(req.headers);
^
ReferenceError: expireToken is not defined
编辑2
我刚刚尝试在expireToken
之前添加tokenManager
,它终于起作用了tl;dr:baz(){this.foo();this.bar()}
在ES2015中,该构造:
var obj = {
foo() { console.log('foo') }
}
等于此ES5代码:
var obj = {
foo : function foo() { console.log('foo') }
}
exports.default={}
类似于创建一个对象,您的默认导出转换为ES5代码,如下所示:
exports['default'] = {
foo: function foo() {
console.log('foo');
},
bar: function bar() {
console.log('bar');
},
baz: function baz() {
foo();bar();
}
};
export default {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { this.foo(); this.bar() }
}
现在很明显(我希望)baz
试图调用foo
和bar
在外部范围中的某个地方定义,但这些都没有定义。但是this.foo
和this.bar
将解析为exports['default']
对象中定义的键。因此,引用其自身方法的默认导出应如下所示:
exports['default'] = {
foo: function foo() {
console.log('foo');
},
bar: function bar() {
console.log('bar');
},
baz: function baz() {
foo();bar();
}
};
export default {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { this.foo(); this.bar() }
}
请参阅。导出默认值{…}构造只是类似以下内容的快捷方式:
exports['default'] = {
foo: function foo() {
console.log('foo');
},
bar: function bar() {
console.log('bar');
},
baz: function baz() {
foo();bar();
}
};
export default {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { this.foo(); this.bar() }
}
const funcs={
foo(){console.log('foo')},
bar(){console.log('bar')},
baz(){foo();bar()}
}
导出默认函数
现在很明显,模块范围内没有foo
、bar
或baz
功能。但是有一个名为funcs
(尽管实际上它没有名字)的对象包含这些函数作为其属性,并将成为模块的默认导出
因此,要修复代码,请在不使用快捷方式的情况下重新编写代码,并将foo
和bar
作为funcs
的属性:
const funcs={
foo(){console.log('foo')},
bar(){console.log('bar')},
baz(){funcs.foo();funcs.bar()}//这是修复方法
}
导出默认函数
另一个选项是使用this
关键字引用funcs
对象,而不必显式声明它
还有一个选项(我通常更喜欢的选项)是在模块范围内声明这些函数。这允许直接引用它们:
函数foo(){console.log('foo')}
函数栏(){console.log('bar')}
函数baz(){foo();bar()}
导出默认值{foo,bar,baz}
如果您想要默认导出的便利性和单独导入项目的能力,还可以单独导出所有功能:
//util.js
导出函数foo(){console.log('foo')}
导出函数栏(){console.log('bar')}
导出函数baz(){foo();bar()}
导出默认值{foo,bar,baz}
//a.js,使用默认导出
从“/util”导入util
util.foo()
//b.js,使用命名导出
从“/util”导入{bar}
bar()
或者,正如@loganfsmyth所建议的,您可以不使用默认导出,只使用“/util”中的
import*as-util来获取一个对象中的所有命名导出。另一种方法是更改模块。通常,如果导出的对象上有一组函数,则更容易导出一组命名函数,例如
export function foo() { console.log('foo') },
export function bar() { console.log('bar') },
export function baz() { foo(); bar() }
在本例中,您将导出所有具有名称的函数,以便
import * as fns from './foo';
要获取具有每个函数属性的对象,而不是第一个示例中使用的导入,请执行以下操作:
import fns from './foo';
我试过了,但没能成功。我用真实代码编辑了这个问题。你能看到这里出了什么问题吗?@chrs,看看我在你问题下的评论。您需要将expireToken
替换为tokenManager。expireToken
@chrs I快了一分钟;)但是我不介意,我喜欢这里的最后一个建议(export default{foo,bar,baz}
),我可能会自己使用它。“如果您想要默认导出的便利性和单独导入项目的能力”,那么您不应该将对象文本作为默认值重新导出,而应该简单地将import*作为util from./util'
。这正是名称空间导入的目的。请参阅my或@pawel的答案。要修复此问题,请将expireToken(req.headers)
替换为tokenManager.expireToken(req.headers)
或this.expireToken(req.headers)
。这无疑是一个更好的解决方案。使用命名导出而不是默认对象。当我像在上一个示例中那样执行此操作时,仍然会得到类型错误:无法读取未定义的属性“foo”
-我缺少什么?