[解決済み] ES6 export defaultで複数の関数が互いに参照し合う場合
質問
es6では、以下のような関数のモジュールを定義することができます。
export default {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { foo(); bar() }
}
は有効なコードのように見えますが、もし私が
baz()
を呼び出すと、エラーを投げます。
ReferenceError: foo is not defined
どのように
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
試しに
tokenManager
の前に
expireToken
で、ようやく動くようになりました。
どのように解決するのですか?
この
export default {...}
の構造は、このようなもののためのショートカットに過ぎません。
const funcs = {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { foo(); bar() }
}
export default funcs
がないことはもう明らかでしょう。
foo
,
bar
または
baz
という関数がモジュールのスコープにあります。しかし
funcs
(という名前のオブジェクトがあり(実際には名前はありませんが)、そのプロパティとしてこれらの関数を含んでいて、それがモジュールのデフォルトのエクスポートになります。
ですから、あなたのコードを修正するには、ショートカットを使わずに書き直し、そのコードを参照するために
foo
と
bar
のプロパティとして
funcs
:
const funcs = {
foo() { console.log('foo') },
bar() { console.log('bar') },
baz() { funcs.foo(); funcs.bar() } // here is the fix
}
export default funcs
もう一つの選択肢は
this
を参照するキーワードです。
funcs
オブジェクトを明示的に宣言することなく参照することができます。
は、@pawel が指摘したように
.
もうひとつの方法(そして私が一般的に好む方法)は、これらの関数をモジュールスコープで宣言することです。これによって、直接参照することができます。
function foo() { console.log('foo') }
function bar() { console.log('bar') }
function baz() { foo(); bar() }
export default {foo, bar, baz}
そして、デフォルトのエクスポートの利便性を求めるなら と の機能を個別にインポートしたい場合は、すべての機能を個別にエクスポートすることもできます。
// util.js
export function foo() { console.log('foo') }
export function bar() { console.log('bar') }
export function baz() { foo(); bar() }
export default {foo, bar, baz}
// a.js, using default export
import util from './util'
util.foo()
// b.js, using named exports
import {bar} from './util'
bar()
あるいは、@loganfsmyth が提案したように、デフォルトのエクスポートを行わず、単に
import * as util from './util'
を使って、1つのオブジェクトですべての名前付きエクスポートを取得することもできます。
関連
-
[解決済み] JavaScriptの "export default "とは何ですか?
-
[解決済み] Export Default Const」が無効なのはなぜですか?
-
[解決済み] Node.jsとES6におけるmodule.exportsとexport defaultの比較
-
[解決済み] Typescriptエクスポートとデフォルトエクスポートの比較
-
[解決済み】Node.jsのrequireとES6のimport/exportを使い分ける。
-
[解決済み】es6のreactコンポーネントがexport defaultでしか動作しないのはなぜ?
-
[解決済み】ES6での`export const`と`export default`の比較
-
[解決済み] <Enter>でjQuery UIダイアログを送信する
-
[解決済み] モバイルWeb HTML5フレームワークの選び方【終了しました
-
[解決済み] <ng-content>が空かどうかを確認する方法は?(これまでのAngular 2+で)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] JavaScriptで次の要素/前の要素を取得しますか?
-
[解決済み] JavaScript で範囲を作成する - 奇妙な構文
-
[解決済み] なぜJavaScriptでは!{}[true]がtrueに評価されるのですか?
-
[解決済み] Node.jsでbase64エンコードされた画像をAmazon S3へアップロードする
-
[解決済み] Google maps API V3 - 同一地点に複数のマーカーを設置する。
-
[解決済み] オブジェクトの配列からReactコンポーネントをレンダリングする
-
[解決済み] TypeScriptプロジェクトで既存のC#クラス定義を再利用する方法
-
[解決済み] JSHintの'+'前の改行不良の説明
-
[解決済み] Node.jsのES6クラスをrequireで作る
-
[解決済み] JavaScriptとLuaの微妙な違い [終了しました]