2015-10-29 4 views
3

У меня есть следующий код:Javascript - не могу понять закрытие

function bird(type) { 
    return function (whattosay) { //return the whole function 
     console.log (type + ' ' + whattosay) 
    } 

} 

var birdRef = bird('blackbird'); 
birdRef('singing in the dead of night'); 

var secondRef = bird('whitebird'); 

birdRef('singing after that night'); 

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

Ну тогда у вас есть это:

var secondRef = bird('whitebird'); 

новый аргумент был принят, так что теперь переменная «тип» изменяется в зависимости от птицы дрозд к Whitebird.

Теперь я вернусь к моим предыдущим создали функцию birdRef, то, что я не понимаю, что происходит дальше:

birdRef('singing after that night'); 

я получаю «дрозд пения после той ночи», вместо Whitebird. Ну, если я не ошибаюсь, разве функция birdRef не попадает в ее родительскую функцию, а читает тип обновленной переменной птицы (я имею в виду, что он не мог найти этот var в локальной среде, поэтому он посмотрел во внешней среде и нашел var "type")?

Извините, если я не имею никакого смысла, поскольку я новичок в этом, и спасибо за ваше время.

+0

Нет, каждый вызов функции создает новый контекст (среду) с отдельной переменной типа. 'birdRef' и' secondRef' - два разных объекта функции, и они закрываются по двум различным переменным. – Bergi

+0

так что, каждый вызов функции птицы создает новую функцию для птиц, подходящую для вызывающего? – RunningFromShia

+0

Правильно, каждая 'bird()' возвращает новую функцию (с тем же кодом, но с другим контекстом) – Bergi

ответ

2

Второй раз, когда вы на самом деле вызываете результат первого закрытия.

Следующая строка:

birdRef('singing after that night'); 

Должно быть:

secondRef('singing after that night'); 

Я включил рабочую демо ниже.

function bird(type) { 
 
    return function (whattosay) { //return the whole function 
 
     console.log (type + ' ' + whattosay) 
 
    } 
 

 
} 
 

 
var birdRef = bird('blackbird'); 
 
birdRef('singing in the dead of night'); 
 

 
var secondRef = bird('whitebird'); 
 
secondRef('singing after that night'); 
 
// ^^ secondRef instead of birdRef 
 

 
// Test is again. 
 
birdRef('singing in the dead of night'); 
 
secondRef('singing after that night');

Поскольку type был определен в лексической области видимости вызова функции, он не доступен за пределами этой лексической области. Как показано выше, если переменная не изменена в пределах лексической области, в которой она была определена, она не может быть доступна или изменена.

+0

Я поставил birdRef во второй раз специально, чтобы увидеть, изменился ли тип птицы из-за предыдущей строки кода, secondRef.идея заключалась в том, чтобы увидеть, влияет ли это на функцию birdRef, потому что birdRef поднимается по цепочке видимости и пытается найти этот «тип» var, недавно измененный secondRef. – RunningFromShia

+1

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

+0

Я написал [демо-версию] (http://jsbin.com/rixusoyira/2/edit?js,console), надеюсь, даст вам лучшее понимание. В основном, когда вы добавляете ключевое слово в список аргументов функции, это ключевое слово идентифицирует переменную, доступную в следующей области, со значением, которое передается в вызове функции. Это то же самое, как если бы вы определяли переменную с помощью ключевого слова var в пределах области функций и присваивали ей статическое значение. –

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