2016-09-08 14 views
0

Прежде чем я погрузится в вопрос, я хочу пояснить, что мой вариант использования включает в себя исправление транс-компилятора для создания надлежащего эквивалента, отсюда и несколько неудобный вопрос.Затенение JavaScript с инициализацией

Я хочу затенять внешнюю переменную, но инициализирую ее так же, как и снаружи. Вот пример:

var a = 2; 
(function(){ 
    var a = a; 
    a += 3; 
    // I want `a` to be 5 
})(); 
// I want `a` to be 2 

Я понимаю, что с приведенным выше примером внутренней a будет NaN (undefined + 3), но я могу инициализировать переменный делает затенение к тому же самому, что она какая-то образом теням? Передача его в качестве аргумента не является вариантом, так как эта функция будет написана пользователем, единственное, что будет последовательным, - это наличие внутренней области. Я думал об изменении имени внутренней переменной a, но компилятор в настоящее время не построен таким образом, чтобы легко отслеживать его, и это создавало бы дополнительные головные боли.

+0

ли "вне переменной" всегда в глобальном масштабе? Все гораздо проще, если это так. – RobG

+0

Нет, он находится в области справа от текущего, обычно –

+0

Хорошо, поэтому ответ Дэнни - это выход. Хотя то, что вы делаете, может быть путаным для тех, кто поддерживает код. – RobG

ответ

0

Поскольку это выражение вызывается сразу же, оно имеет совершенно другую область действия, чем код, написанный за его пределами. Невозможно делать то, что вы просите, не передавая каким-либо аргументом (непосредственно при выполнении или использовании привязки) или изменяя функцию, поэтому область действия - область действия, в которой определяется требуемый var a.

С учетом сказанного возможно вы можете вернуть некоторые методы, которые установили a в соответствующее значение.

http://jsbin.com/vazequhigo/edit?js,console

var a = 2; 
w = (function(){ 
    var setA = function(val) { 
     a = val; 
    } 
    var addA = function(val) { 
     a += val; 
     return a; 
    } 

    var a = 0; 

    return { 
     setA: setA, 
     addA: addA, 
    }; 
})(); 

w.setA(a); 
console.log(w.addA(3)); 
+0

Область действия не может быть изменена в любом случае. * bind * используется для установки * this *, что совсем другое. – RobG

+0

@RobG после передачи значения 'this' в качестве первого параметра метода' bind' вы можете передать дополнительные аргументы в метод 'bind', который будет добавляться к аргументам, предоставленным связанной функции при вызове целевой функции. –

+0

Кроме того, @RobG область действия может быть изменена путем изменения способа определения функции. Определяя регулярную функцию, а не IIFE, функция будет иметь доступ к «var a» из внешней области. –

4

Вам необходимо пройти a в качестве параметра в вашем IIFE.

(function(parameter){ 
// «parameter» contains the given value. 
// parameter = "Some value". 
})("Some value"); 

Что-то вроде этого:

var a = 2; // Variable declaration in the global scope. 
 
(function(a) { 
 
    a += 3; 
 
    // I want `a` to be 5 
 
    console.log(a); // Prints the current value in the local scope. 
 
})(a); // The parameter: var a = 2; 
 
console.info(a); // Prints the current value in the global scope. 
 
// I want `a` to be 2