2010-02-19 4 views
8

Кто может объяснить, почему результат являются [20, 20, 10, 10] в этом коде:Javascript область видимости функции

var x = 10; 
var foo = { 
    x: 20, 
    bar: function() { 
    var x = 30; 
    return this.x; 
    } 
}; 

console.log(
    foo.bar(), 
    (foo.bar)(), 
    (foo.bar = foo.bar)(), 
    (foo.bar, foo.bar)() 
); 

Ссылки по спецификации приветствуются

+0

в IE кажется, что выход 20,20, undefined, undefined .. – RameshVel

ответ

7

Не могу указать вас по спецификации, но я могу очень рекомендовать чтение Douglas Crockford's "Javascript: The good parts". Эта книга поможет вам понять большинство странных, но отличных функций JavaScript.

На ваш вопрос:

  1. foo.bar(), this ключевое слово в bar функции привязан к объекту foo
  2. (foo.bar)() такая же, как и выше,
  3. В javascript вы можете назначить переменные справа налево несколько раз

    z = 3; x = (y = z); console.log (x); // 3

функции являются переменными как что-либо еще. Таким образом, вы назначаете функцию foo.bar на foo.bar, но скобка приводит к возврату назначенной функции и последующему ее выполнению.

(foo.bar = foo.bar)(); 
//is the same as 
var f = (foo.bar = foo.bar); 
f(); 
//and this also the same as: 
var f= foo.bar; 
f(); 

Функция возвращается из скобки не связана ни к чему, так this будет ссылаться на глобальный объект, в случае браузеров - к window объекту.

4 .. Предложение (foo.bar, foo.bar)() просто так:

a = (3, 4); //last value is returned, first just parsed. 
//a contains 4 

var f = (foo.bar, foo.bar); 
//f contains body of foo.bar function, 
f() // is executed in the context of `global` object, eg. `window`. 

Пожалуйста, прочтите о binding функций в JavaScript.

0

Я думаю, что следующий question будет полезно для этого.

0

Первые два вызова функций эквивалентны. Они вызывают метод foobar в контексте foo - поэтому значение, возвращаемое this.x, является значением foox, которое составляет 20.

Вторые два вызова являются как сомнительными, так и недействительными. Попробуйте запустить код через JSLint, и вы увидите, что он выплевывает несколько ошибок, а затем полностью задыхается. Мое лучшее предположение о том, почему они возвращают 10, состоит в том, что он пытается проанализировать ваш код в случае, когда он действительно не должен и запутывается. 10 может быть возвращен, потому что браузер не может понять, что вы пытаетесь сделать, и по умолчанию используется глобальная область (окно), где значение x равно 10. Это также объясняет комментарий Рамеша Веля, что два вторых значения отображаются как undefined в IE. Из-за того, что синтаксис недействителен, различные реализации JavaScript, скорее всего, будут обрабатывать их по-разному.

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