2014-11-11 2 views
3

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

var foo = { 
    bar: {} 
}; 
(function(foo, bar) { 
    foo.bar = 'a'; 
    bar = 'b'; 

}(foo, foo.bar)) 

console.log(foo.bar) // prints 'a', not 'b', how come? 

ответ

6

определяются две переменные:

function(foo, bar) 

Вы передаете два значения в них:

}(foo, foo.bar)) 

Значение foo является ссылкой на объект (т.е. объект имеет свойство bar значение которого является ссылкой на другой объект)

Значение переменной bar является ссылкой на этот второй объект.

foo.bar = 'a'; 

Вы перезаписать bar свойство первого объекта со строкой 'a'. foo.bar больше не является ссылкой на второй объект. Значение bar по-прежнему является ссылкой на второй объект.

bar = 'b'; 

перезаписывается локальной bar переменного со строкой 'b'. В настоящее время нет ссылок на второй объект слева. Второй объект будет собирать мусор.

console.log(foo.bar) 

Вы выводить значение bar свойства объекта, что значение foo является ссылкой. Это 'a', так как вы изменили значение этого свойства в функции.

+0

Не совсем корректно. Попробуйте следующее: 'var foo = {bar: {}}; (function (bar) {bar = 'b';} (foo.bar)); console.log (foo.bar); ' – SimonSimCity

+1

@SimonSimCity - это просто удаляет все экземпляры модификации« первого объекта », поэтому, когда вы запускаете console.gog, вы получаете второй объект (потому что вы не перезаписали свойство bar * * первого объекта). Как это противоречит моему ответу? – Quentin

+1

@SimonSimCity Что об этом? Он работает так, как я ожидаю. – Scimonster

4

foo является объектом, который передается по ссылке. bar передается по значению. Когда bar перезаписано, оно теряет отношение к foo.bar. Следовательно, foo.bar является «a», что и было установлено в функции.

var foo = { 
    bar: {} 
}; 
(function(foo, bar) { 
    // foo is {bar:{}} 
    // bar is {} 
    foo.bar = 'a'; 
    // now foo is {bar:'a'} 
    bar = 'b'; 
    // now bar is 'b' 
    // bar has no relation to foo.bar anymore 

}(foo, foo.bar)) 

console.log(foo.bar) // prints 'a', not 'b', how come? 
+0

Я думаю, что OP спрашивает, что 'foo' внутри функции не равно' foo' вне области видимости функции. Она должна печатать '{}', но не 'a'. Возможно, я ошибаюсь. –

+0

'foo' относится к одному и тому же объекту в обеих областях. – Scimonster

+0

'foo.bar' (аргумент функции) также является объектом. Ни параметры 'foo', ни' bar' не передаются по ссылке – Bergi

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