LoginSignup
3
0

More than 5 years have passed since last update.

JavaScriptのES6のmoudleでimportした変数をFunction コントラクタの中で使う方法

Last updated at Posted at 2018-01-27

背景

ブラウザで動くjavascriptエディター jsnoteを作っていた. Functionコンストラクタでユーザが入力したコードを実行できるようにした. ES6のモジュールで作った変数をそのエディタでよんでも実行できなくて困った.

問題

ブラウザでES6のmoduleでimportした変数をFunctionコントラクタの中で呼べない.
実行環境: Chrome ver63

import * as myapp from "./myapp/index.mjs"
myapp.sample() // OK
let code = "myapp.sample()"
new Function(code)() // ERROR

consoleでmyappが存在しないと言われて実行できない

原因

MDNによると同じjavascriptのファイル内に書いた変数はスコープが違うからFunctionの中で呼び出せない.

Function コンストラクタによる関数の生成は、生成コンテキストにクロージャを作りません。つまり常にグローバルスコープで作成します。これを実行すると、 Function コンストラクタの呼び出し元のスコープは入らず、自身のローカル変数とグローバル変数だけにアクセスできます。これは関数式のコードに eval を使うのとは異なっています。

MDNへのリンク

たとえ、varを使ってグローバル変数に入れても効かない.

import * as myapp from "./myapp/index.mjs"
myapp.sample() //  OK
var MYAPP = myappp
let code = "myapp.sample()"
new Function(code)() //  ERROR

対処法

windowのプロパティに入れてグローバル変数にすると使える

import * as myapp from "./myapp/index.mjs"
myapp.sample() //  OK
window.myapp = myapp
let code = "myapp.sample()"
new Function(code)() //  OK
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0