Как не имеет доступа к определенным переменным доступа к выделенным переменным?

StackOverflow https://stackoverflow.com/questions/3431689

  •  26-09-2019
  •  | 
  •  

Вопрос

Почему Вы не можете получить доступ к спешенным переменным, используя eval под with утверждение?

Например:

(function (obj) { 
   with (obj) {
      console.log(a); // prints out obj.a
      eval("console.log(a)"); // ReferenceError: a is not defined
   }
})({ a: "hello" })

РЕДАКТИРОВАТЬ: Как отметил знающий CMS, это похоже на ошибку браузера (браузеры, которые используют консоль WebKit).

Если кому-то было интересно, какая мердинация я пытался придумать, что потребует как «зло» eval и with - Я пытался посмотреть, смогу ли я получить функцию (используется в качестве обратного вызова), выполненной в другом контексте, а не тот, который он был определен. И нет, я наверное (Кашель) не будет использовать это нигде .. Более любопытно, чем все.

(function (context,fn) { 
    with (context) 
       eval("("+fn+")()"); 
})({ a: "hello there" }, function () { console.log(a); })
Это было полезно?

Решение

Это ошибка, воспроизводимая только из консоли WebKit, у него есть проблемы, связывающие контекст вызывающего абонента, когда eval вызывается из FunctionExpression.

Когда прямой звонок eval Изготовлен, оцененный код, как вы ожидаете, должен делиться как вариабельной средой:

(function (arg) {
  return eval('arg');
})('foo');
// should return 'foo', throws a ReferenceError from the WebKit console

А также лексическая среда:

(function () {
  eval('var localVar = "test"');
})();

typeof localVar; // should be 'undefined', returns 'string' on the Console

В приведенной выше функции localVar следует заявить о лексической среде абонента, а не в глобальном контексте.

За FunctionDeclarationS Поведение совершенно нормально, если мы попробуем:

function test1(arg) {
  return eval('arg');
}
test1('foo'); // properly returns 'foo' on the WebKit console

И

function test2() {
  eval('var localVarTest = "test"');
}
test2();
typeof localVarTest; // correctly returns 'undefined'

Я смог воспроизвести проблему на следующих браузерах, работающих на Windows Vista SP2:

  • Chrome 5.0.375.125.
  • Chrome 6.0.472.25 Dev
  • Safari 5.0.1.
  • WebKit Nightly Build R64893

Другие советы

(function (obj) {
   with (obj) {
      alert(a); // prints out obj.a
      eval("alert(a)"); // ReferenceError: a is not defined
   }
})({ a: "hello from a with eval" })

function testfunc(a) { eval("alert(a)"); } testfunc("hello from a testfunc eval");

(function (a) { eval("alert(a)"); })("hello from a function constructor eval")

Все работает нормально: http://polyfx.com/jstest.html. в FF / Chrome / Safari / IE.

Проблема с запущенными фрагментами кода из различных консолей состоит в том, что консоли обычно винт с контекстом. (т.е. Chrome Console не имеет должным образом упаковочным материалом в глобальном контексте, в то время как консоль Firebug делает). Это может быть ошибка или (скорее всего), она могла работать как предполагаемое.

Eval всегда работает в глобальном масштабе, не так ли?

В отставке EVAL и со стороны New Bowsers включают в себя функцию ECMA5.prototype.BIND-метод для вызова функции в объеме выбранного объекта.

Для более старых браузеров вы можете подделать

Function.prototype.bind= Function.prototype.bind || function bind(scope){
    var method= this;
    return function(){
        method.apply(scope, arguments);
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top