Как получить значение затененной глобальной переменной? - PullRequest
6 голосов
/ 24 ноября 2011

Пример:

var test = 'global value';

(function() {
    var test = 'local value';

    // how to get the 'global value' string
})();

Учитывая условие, что среда хоста неизвестна, это означает, что мы не можем предполагать, что глобальный объект будет доступен через имя window.Кроме того, функция не может получать аргументы!

Ответы [ 5 ]

4 голосов
/ 24 ноября 2011

Исправление

var test = 'global value';

(function() {
    var test2 = 'local value';

    console.log(test);
})();

Реальное решение состоит в том, чтобы исправить ваш код так, чтобы вы не следили за глобальными переменными, которые вас волнуют.

Eval Work вокруг

Вы всегда можете использовать глобальный eval, он самый надежный.

Пример

var test = 'global value';

function runEval(str) {
  return eval(str);
}

(function() {
    var test = 'local value';

    console.log(runEval("test"));
})();

Если вам не нравится определять глобальный eval, вы можете использовать Function, чтобы сделать это косвенно

Живой пример

var test = 'global value';

(function() {
    var test = 'local value';

    console.log(new Function ("return test;") () );
})();

Разные хаки

Следующие работы в нестрогом режиме

(function () {
  var test = "shadowed";

  console.log(this !== undefined && this.test);
})();

И этот хак работает в сломанных реализациях

(function() {
    var test = 'local value';

    try { delete test; } catch (e) { }

    console.log(test);
})();
1 голос
/ 24 ноября 2011

Принципиально большая проблема, если вы хотите сделать это в коде строгого режима, это получение глобального объекта. К счастью, есть несколько простых способов: var global = (1,eval)("this"); (который не работает в каждом браузере, поскольку его поведение не определено в ES3, хотя и определено в ES5) или var global = (new Function("return this"))(); (который работает).

Итак, соберите вместе с тем, что вам нужно, у вас может быть такая функция:

function getGlobal(name) {
  "use strict";
  var global = (new Function("return this"))();
  return global[name];
}

Вероятно, было бы лучше избегать затрат на создание функции каждый раз, поэтому было бы лучше что-то вроде следующего:

var getGlobal = (function() {
  "use strict";
  var global = (new Function("return this"))();
  return function(name) {
    return global[name];
  }
})();
1 голос
/ 24 ноября 2011

Как насчет того, чтобы полагаться на this в качестве глобального объекта (без явной ссылки на window).

console.log(this.test);

jsFiddle .

Вы можететакже используйте косвенный вызов eval() (execScript() здесь для целей IE, но не стесняйтесь игнорировать, как вы упомянули, чтобы не использовать браузер).

console.log((window.execScript || eval)('test'));

jsFiddle .

0 голосов
/ 24 ноября 2011

Другим решением является запоминание глобального объекта:

var test = "global";
function called() {
    var test = "local";
    alert(arguments.callee.window.test); // alerts "global"
}
called.window = this;
called();
0 голосов
/ 24 ноября 2011

Это зависит."Нахальный" способ обойти "не разрешено принимать какие-либо аргументы" может заключаться в использовании call:

var test = 'global value';

(function() {
    var test = 'local value';

    var globalTest = this.test;
}).call(this);

Но если вы можете рассчитывать на this, являющийся глобальным объектом, когда нет this явно указано, тогда this.test будет работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...