5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Evaluating JavaScript code via indirect eval call.

Last updated at Posted at 2015-07-02

このエントリは、indirect eval call を使い global を取得する方法についてのメモです。

(0, eval)('this')とは何なのか を拝見したのがこのメモを記述するきっかけです。

このイディオム(indirect eval call)に関連する記事としては、以下の3つが見つかりました。2つめは Dr.Axel さんのものですね。

  1. http://pirosikick.hateblo.jp/entry/20110517/1305645797 ("global", eval)("this")
  2. http://www.2ality.com/2014/01/eval.html Evaluating JavaScript code via eval() and new Function()
  3. http://stackoverflow.com/questions/19357978/indirect-eval-call-in-strict-mode Indirect eval call in strict mode

書き方としては (0, eval)('this') に限らず、亜種がいっぱいあるようです。
要は、一旦 eval を変数(または暗黙の変数)に入れると indirect eval call として扱われるようです。

(1, eval)('...')
(eval, eval)('...')
(1 ? eval : 0)('...')
(__ = eval)('...')
var e = eval; e('...')
(function(e) { e('...') })(eval)
(function(e) { return e })(eval)('...')
(function() { arguments[0]('...') })(eval)
this.eval('...')
this['eval']('...')
[eval][0]('...')
eval.call(this, '...')
eval('eval')('...')

in Babel

Babel だとどうなるのでしょうか?

indirect eval call で global が取得できるか、 Babel の repl で試してみた結果がこちらです。

// source
var a = (0, eval)("this");

console.log(Object.prototype.toString.call(a));
// result

"use strict";

var a = (0, eval)("this");

console.log(Object.prototype.toString.call(a)); // [object global]

遅延評価されることで global がとれてますね。

なお、
(0, eval)("this"); と文字列にせず、
(0, eval)(this); としてしまうと、
Babel が (0, eval)(undefined); に変換してしまいます。

in ESLint

ESLint で eval がどのように扱われているかも知る必要があるでしょう。

.eslintrc を用意し実行してみます。

{
    "env": {
        "browser":          true,
        "node":             true
    }
}

$ eslint ...

私の環境では特に怒られませんでした。良いですね。

vs WebModule

蛇足になりますが、uupaa さん家の WebModule では、
var GLOBAL = GLOBAL || (this || 0).self || global;global Object を求めていますね

なんだか、WebModule のやり方よりも
var global = ("global", eval)("this"); のほうがシンプルでスッキリしている、そんな気がしてきました。

まとめ

まとめると、var global = ("global", eval)("this"); は、(困った事に)中々良いのではないでしょうか。

あ、そうそう初Qiita なのでお手柔らかにお願いします。

5
4
1

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
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?