очевидно, b
не определен, так она стала глобальной переменной
только в свободном режиме. Не используйте свободный режим. :-) Используйте строгий режим, где это будет ошибка, которой он всегда должен был быть.
теперь, что происходит, когда вы меняете b
в глобальном масштабе, делает значение a
изменений также?
Нет, между a
и b
нет ссылки. Переменные содержат значения (подробнее об этом ниже). Когда вы делаете a = b
, значение в b
копируется в a
. Связь между этими двумя переменными не создается.
интервьюер может задавать вопрос с подвохом (они так любят, чтобы сделать это), и/или он/она может попасть в общую ошибку, так что продолжайте читать ... :-)
Я не уверен, как проверить этот
Поскольку мы находимся в свободном режиме, мы знаем, что вызов сырой функции установит this
ссылаться на глобальный объект во время вызова. Так как неявное b
глобальный будет свойство глобального объекта, мы можем проверить это путем изменения this.b
(глобальный):
function foo() {
var a = b = 3;
console.log("(Before) a is " + a + ", b is " + b);
this.b = 10;
console.log("(After) a is " + a + ", b is " + b);
}
foo();
(В браузерах мы могли бы использовать window
вместо this
выше , так как window
является глобальным по умолчанию в браузерах, который относится к глобальному объекту.)
Стоит отметить, что, хотя есть только один b
, там будет b e a a
для каждого вызова foo
в вышеуказанном виде. Но я не думаю, что это действительно затрагивает вопрос.
В комментарии вы спросили о «ссылочных переменных». В JavaScript нет «ссылочных переменных». Вы, вероятно, думаете об объектных ссылках. Ключевой факт: не имеет значения, о чем мы говорим (изменит ли b
изменение a
?), Содержит ли переменная ссылку на объект или примитив.Но это распространенная ошибка, в которую люди попадают (возможно, даже интервьюер задает вопрос :-)) до думаю, что это важно. Но они путают изменение b
(переменная) с изменением состояния объекта b
.
Переменные содержат значения. Когда вы назначаете ссылку на объект для переменной, эта ссылка на объект представляет собой значение , которое сообщает движку javaScript, где объект находится в памяти. Например:
var b = {answer:42};
В памяти, мы имеем:
+------------+
[b:REF55134]-----| (object) |
+------------+
| answer: 42 |
+------------+
значение в b
является ссылкой на объект. Я представил его выше как REF55134
, но мы никогда не можем получить доступ к исходному значению этой ссылки. Это необработанное значение не имеет значения, это всего лишь вещь (сродни номеру), которая сообщает движку JavaScript, где находится объект.
Теперь, если мы делаем это:
var a = b;
... мы копируем значение из b
в a
, и получить это в памяти:
[b:REF55134]--+
| +------------+
+-->| (object) |
| +------------+
[a:REF55134]--+ | answer: 42 |
+------------+
a
и b
имеют одинаковые значение в них, и поэтому они оба указывают на один и тот же объект.
Изменение b
по-прежнему не имеет никакого эффекта на a
. Здесь люди путаются в том, что если мы изменим состояние объекта объекта b
, то, естественно, мы можем видеть, что изменившееся состояние было также a
. Значение в b
не изменилось, состояние вещи, которое оно указывает на изменение.
т.д .:
b.question = "Life, the Universe, and Everything";
дает нам:
[b:REF55134]--+
| +------------------------------------------------+
+-->| (object) |
| +------------------------------------------------+
[a:REF55134]--+ | answer: 42 |
| question: "Life, the Universe, and Everything" |
+------------------------------------------------+
b
не изменился, объект изменился. Поэтому, естественно, если бы мы сделали console.log(a.question);
, мы увидели бы знаменитый вопрос, потому что a
и b
указывают на тот же объект.
Если мы на самом деле изменить b
, это не оказывает никакого влияния на a
на все:
b = {foo:"bar"};
+------------+
[b:REF14359]----->| (object) |
+------------+
| foo: "bar" |
+------------+
+------------------------------------------------+
[a:REF55134]----->| (object) |
+------------------------------------------------+
| answer: 42 |
| question: "Life, the Universe, and Everything" |
+------------------------------------------------+
Обратите внимание, что теперь b
имеет другое значение в этом, ссылаясь на другой объект.
Зачем «а» меняться, если 'b'? Даже если бы они были глобальными. – nnnnnn
@nnnnnn im не уверен, что такое контекст, где переменные являются ссылками на другие переменные, и в этом случае они могут измениться, когда другой делает – codemonkey
JS-переменные не относятся к другим переменным, они относятся к значениям/объектам. – nnnnnn