2016-07-10 2 views
1

так quesiton я имел для Js интервью в основном с участием сферы и переменными во внутренней функции, например, предполагается, вы имели в этом:Javascript сферы задающего

function(){ 
var a=b=3; 
} 

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

Я не уверен, как проверить это, но, например, если вы изменили b на 10, будет ли теперь 10 или он останется 3?

+0

Зачем «а» меняться, если 'b'? Даже если бы они были глобальными. – nnnnnn

+0

@nnnnnn im не уверен, что такое контекст, где переменные являются ссылками на другие переменные, и в этом случае они могут измениться, когда другой делает – codemonkey

+0

JS-переменные не относятся к другим переменным, они относятся к значениям/объектам. – nnnnnn

ответ

8

очевидно, 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 имеет другое значение в этом, ссылаясь на другой объект.

+0

ах это то, что я думал, но я также помню что-то о ссылочных переменных, где можно изменить значение одного, изменив другое, но забыл контекст, в котором это происходит. – codemonkey

+0

_Variables указывают на местоположения_ – sheriffderek

+0

@codemonkey: в JavaScript нет «ссылочных переменных». Вы, вероятно, думаете об объектных ссылках. Я добавлю записку о них. –

2

В этом случае, поскольку 3 является примитивным типом числа. Таким образом, он использует примитивный тип данных для назначения b и назначения a. Примитивные значения в JavaScript определяют неизменные значения.Это означает, что ценность, которую он имеет, никак не изменится из-под вас.

Вопрос немного вводит в заблуждение. Значение a будет отличаться, если b меняется каждый раз при вызове функции. Каждый раз это другая переменная a, хотя и не одна. a выходит за пределы сферы действия, хотя, кто заботится о a? Функция эквивалентна функции с телом b = 3. На стороне примечание, изменение любого глобального состояния в функции плохой дизайн.

ECMAScript 6 определяет семь типов данных (логические, нулевые, неопределенные, числовые, строковые, символьные, объекты), причем все являются примитивными, за исключением объектов.

Было бы полезно прямо указать в интервью, что вы понимаете, что с объектами было бы иначе, если бы a не выходил за рамки моментально. В этом случае изменение свойства на b также будет отражено в a. Но смена b полностью не повлияет на a. Зачем? Потому что, когда вы меняете свойство, вы изменяете изменяемое значение, а не переменную. Вы можете пойти дальше и объяснить, что использование объекта-обертки Number также работает по-другому.

Вы также получите бонусные баллы за упоминание, что предоставленный им код недействителен в строгом режиме. Вы можете указать, что используете строгий режим, используя "use strict"; в верхней части файла, или вы можете также ограничить режим строгой работы внутри функции, только сделав ее первым утверждением в своей функции. В модульной системе ES6 по умолчанию включен строгий режим.

На стороне примечание, так как a выходит из сферы действия сразу, вопрос настолько плох, что это может означать, что плохой кодер проводит собеседование с вами. В каждой реализации JavaScript, о которой я знаю, это не многопоточная среда ...

+0

* "В этом случае, поскольку 3 имеет тип' Number' "* 3, это' number' (примитив), а не 'Number' (тип объекта), а тип 3 не имеет никакого отношения к тому, b' позже повлияет на 'a'. –

+0

Вы имеете в виду 'Number', являющийся конструктором, есть также тип« Number », если вы не верите мне, чтобы проверить здесь https://tc39.github.io/ecma262/#sec-terms-and- definition-number-type –

+0

Конечно, тип 3 не имеет значения, так как он выходит за пределы области действия, а JS - однопоточная среда.Но если бы он не выходил из сферы действия, было бы абсолютно важно, чтобы 3 был вместо него каким-то другим объектом и свойство на этом объекте было изменено. –