2013-07-10 3 views
0

Что было бы правильным способом добиться чего-то подобного, не привязывая его к объекту окна?Ввод переменных в замыкание

x = function(fn) 
{ 
    foo = 'bar'; 
    fn(); 
} 

x(function() 
{ 
    console.log(foo) // error happens here 
}); 

В PHP вы можете использовать директиву «use».

$foo = 'bar'; 
$fn = function() use($foo) 
{ 
    echo $foo; // bar 
} 

Редактировать: Я немного изменил часть кода. То, что я пытаюсь достичь, состоит в том, чтобы сделать объявленную переменную доступной в закрытии, без необходимости передавать ее там.

foo = 'bar'; 
console.log(foo) // bar 
console.log(window.foo) // bar 
console.log(this.foo) // bar 

Я хочу добиться такого же эффекта, с другим объектом, который был связан как «это».

+3

Я не понимаю, что вы хотите. Я просто надеюсь, что ответ не «с». –

+0

Что значит «без привязки к объекту окна»? Когда вы делаете закрытие, вы делаете привязку к охватывающей сфере. –

+3

Это не должно сказать 'undefined'. Хорошо работает здесь http://jsbin.com/evacak/1/edit – elclanrs

ответ

7

Ну, угадайте, что у JavaScript есть real закрытий. Не полупеченые, как PHP, где вам нужно вручную объявить все переменные в закрытии, которые вы хотите использовать.

эквивалент этого PHP кода:

$foo = 'bar'; 
$fn = function() use($foo) 
{ 
    echo $foo; // bar 
} 

Является ли это в JS:

var foo = 'bar'; 
var fn = function() { 
    console.log(foo); 
}; 

Угу. Вы не называете свою функцию на PHP, почему я бы назвал ее в примере JS? :-)

Кстати, если запустить этот бит кода в JS консоли:

var foo = 'bar'; 
var fn = function() { 
    console.log(foo); 
}; 
fn(); 

Вы увидите «бар» вошли. Доказательство того, что замыкания работают без необходимости взлома. (use)

Что касается глобальных переменных: переменная $foo является глобальной в вашем примере PHP. Они также приведены в примере JS. Если вы хотите иметь не-глобальную переменную, вам нужна локальная среда. В большинстве случаев функция.

PHP пример с не-глобальные переменные:

function baz() { 
    $foo = 'bar'; 
    $fn = function() use ($foo) { 
     echo $foo; 
    }; 
} 

JS пример с не-глобальные переменные:

function baz() { 
    var foo = 'bar'; 
    var fn = function() { 
     console.log(foo); 
    }; 
} 

Последнее замечание: если вы не используете var объявить новый переменные в JS, это подразумеваемые глобальные значения. В браузере это означает, что они прикреплены к объекту window.

Если вы хотите PHP/сравнение JS, как объявлять глобальные переменные:

PHP код:

$foo; // global 
function bar() { 
    $_GLOBAL['baz']; // global 
    $bin; // local 
} 

JS код:

foo; // global 
function bar() { 
    window.baz; // global 
    var bin; // local 
    booze; // implied global 
} 
+0

+1 Это похоже на первое объяснение путаницы OP ... –

+0

You 'используя ту же область действия, поэтому он работает в вашем примере.Если вы передадите fn несколько раз через другие функции, это больше не будет работать. Но мой пример был очень плохим, так что все в порядке. Спасибо! –

+0

@maximkott, который тоже не работал бы в PHP. Я не понимаю, что я думаю ... –

-1

Если я правильно понимаю вашу потребность, вы можете сделать это:

var closure_variables = new Object();; 
closure_variables.foo = 'bar'; 
window.bar = 'foo' 

(function(variables) 
{ 
    console.log(variables.foo) // undefined 
    console.log(bar) // foo 
})(closure_variables) 

Или вы даже можете перейти непосредственно Foo в аргументах.

+2

Вы делаете ту же ошибку, что и другой аналогичный (идентичный?) Ответ. –

+0

О, правда, спасибо dude – Ricola3D

+0

Я предлагаю дубликат комментария .. это также потребует '(function (clos_variables)' – Orangepill

0

Если вы хотите сохранить окно объект чист, это может быть то, что вам нужно.

(function(){ 

    var foo = 'bar'; 

    (function(){ 
     console.log(foo) // bar 
    })(); 

})(); 

console.log(window.foo); //undefined 
0

Ответ заключается в том, что в PHP вы выбираете, что входит в комплект. В JS нет возможности сказать закрытию, чтобы выбрать, какие переменные должны быть заключены. Все лексически доступные переменные прилагаются.

Но это трудно сказать, что вы хотите, это выглядит, как вы хотите, чтобы скрыть замыкание переменной

Единственный способ решения проблемы заключается в тени переменных (объявляя их внутренней функции) вы не хотите

+0

Вот что я подумал :( –

+0

Интересно, хочет ли OP '.call()' определить значение 'this' в пределах функция (что не обязательно является проблемой закрытия)? –

+0

Подождите, что? Почему вы хотите затенять переменные закрытия? Это первый раз, когда я услышал такой хак ('use'), упомянутый как функция :-) –

0

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

Для вызова функции fun настройки this в objectThatBecomesThis, а также устанавливая аргументы (arg1, arg2, ...) использовать:

fun.apply(objectThatBecomesThis, [arg1,arg2,...]) 

где второй параметр (необязательный) представляет собой массив аргументов для функция.

Поскольку второй параметр представляет собой массив, он использует квадратные скобки [].

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

Смежные вопросы