Объявите переменную, используя 'var' в операторе with {} - PullRequest
1 голос
/ 16 октября 2019

Я только изучаю книгу You-dont-know-js на github, в настоящее время закрытие области действия, глава 2: https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/scope-closures/ch2.md

Я столкнулся с проблемой, которая мне не ясна: объявить переменную с помощью 'var'в выражении with {}. Вот объяснение относительно этого:

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

В соответствии с этим объяснением я немного изменил код, приведенный в этой главе:

function foo(obj) {
	with (obj) {
		var a = 2;  //Here I added "var" declaration 
	}
  console.log('foo, '+ a)  //Here I added console function to see if a is in foo scope
}

var o1 = {
	a: 3
};

var o2 = {
	b: 3
};

foo( o1 );   // foo, undefined
console.log( o1.a );     //2

foo( o2 );   // foo, 2
console.log( o2.a );    //undefined

для foo (o2), я понимаю, что, поскольку у o2 нет свойства с именем 'a', объявление var внутри блока with только что создало переменную a внутри функции fooсфера, и результат имеет смысл. но для foo (o1) объявление var только что изменило o1.a на значение 2, но почему console.log ('foo,' + a) показывает 'foo, undefined'? Как я понимаю, результатом должно быть либо 'foo, 2', либо ошибка ссылки: a не определено.

Может кто-нибудь объяснить эту проблему? спасибо.

1 Ответ

0 голосов
/ 16 октября 2019

Что делает компилятор:

function foo(obj) {
    var a;                   // hoisted
    with (obj) {
        a = 2;               // take a from object if exists, otherwise take variable
    }
    console.log('foo, '+ a);
}

Первый случай создает переменную a в области действия функции, затем оператор var удаляется / поднимается и остается только часть назначения.

И хотя obj содержит свойство a, значение присваивается свойству объекта с помощью оператора with.

Локальный a не получил никакого значения.

Во втором вызове отсутствует свойство a, и поэтому переменная a получает значение.

...