2016-08-30 8 views
0

Я понимаю, что происходит с этой в этом простом коде:Confused этим поведением JavaScript в конкретной ситуации

function foo() { 
    alert(this.a); 
} 

function doFoo(fn) { 
    a = "local"; 
    fn(); 
} 

var a = "global"; 

doFoo(foo); 

Из того, что я узнал, deFoo контекст объект, из которого Foo называется так, что сообщение предупреждения должно быть «локальным». Это работает, если я не объявить в внутри doFoo:

function doFoo(fn) { 
    var a = "local"; 
    fn(); 
} 

Теперь предупредительное сообщение является «глобальным». Может кто-то объяснить это мне? Я новичок в Javascript.

+0

https://github.com/getify/You-Dont-Know-JS/tree/master/scope%20% 26% 20closures – cbass

+2

Возможный дубликат [Как работают блокировки JavaScript?] (Http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) –

+0

'this' является сумасшедшим ... – openwonk

ответ

1

Несколько вещей, которые будут рассматриваться:

  1. value это определяется тем, как function называется!
  2. Если function вызывается под global-context, this относится к window (в браузере)
  3. Если variable не определен с использованием ключевого слова var, это глобальная переменная.

В вашем примере, a внутри функции doFoo относится к window.alocal которая, перезаписывается при вызове функции.

function foo() { 
 
    alert(this.a); 
 
} 
 

 
function doFoo(fn) { 
 
    console.log(window.a); 
 
    a = "local"; //window.a is set to "local" 
 
    fn(); 
 
} 
 
var a = "global"; //window.a is "global" 
 
doFoo(foo); 
 

 
//Few logs to make it clear 
 

 
console.log(window.doFoo); 
 
console.log(window.a);

+0

Почему функция, вызываемая в рамках глобальной -context? Я думал, что контекст определяется сайтом-вызовом, а call-сайт - doFoo. Это меня смущает. – Rrmm

+0

@Rmm, когда вы говорите 'var a =" global "' outside, тогда do 'a =" local "' внутри функции, глобальная переменная становится 'local'. Если вы добавите 'var', перед ним будет рассматриваться его как локальная переменная' a'. –

+0

@Rrmm - Проверьте журналы в обновлении ... – Rayon

0

Javascript имеет lexical scope, поэтому в вашем примере this всегда относится к глобальной версии a, который получает перезаписаны в первом фрагменте.

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

0

Первый a является global, то мы называем doFoo, то globala установлен в local.

Теперь мы вызываем fn(), который вызывает foo(), здесь this относится к текущему контексту выполнения. Здесь this относится к области global.

Таким образом предупреждая local

Extra домашнее задание для вас: Следуя подобной логике, почему следующее предупреждение global?

var a = "global" 

function thisA() 
{ 
    var a = "local"; 
    fn(); 
} 

function fn() 
{ 
    alert(this.a); 
} 

thisA(); 

Примеры по размаху

1.

var a = 3; 
function myA() 
{ 
    a = 2; 
} 

myA(); 
console.log(a); // 2 

2.

var a = 3; 
function myA() 
{ 
    var a = 2; 
} 

myA(); 
console.log(a); // 3 

3.

var a = 3; 
function myA() 
{ 
    var a = 2; 
    myOtherA(); 
} 

function myOtherA() 
{ 
    a = 4; 
} 

myA(); 
console.log(a); // 4 since myOtherA() sets the global var a = 3 to 4, NOT myA(); 

4.

var a = 3; 
function myA() 
{ 
    var a = 2; 
    function withinA() 
    { 
     a = 10; 
    } 
    withinA(); // changes var a = 2, to 10 NOT the outer a =3 
} 



myA(); 
console.log(a); // Still 3 
Смежные вопросы