2016-08-30 67 views
0

我被什麼在這個簡單的代碼發生困惑迷茫:通過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' is crazy ... – openwonk

回答

1

幾件事情:

  1. value確定由function怎麼叫!
  2. 如果function被下global-context調用,thiswindow(在瀏覽器)
  3. 如果variable不使用關鍵字var定義,它是全局變量。

在你的榜樣,a內部功能doFoowindow.a這是local,被調用函數時覆蓋。

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?我認爲上下文是由呼叫站點決定的,呼叫站點是doFoo。這讓我感到困惑。 – Rrmm

+0

@Rmm,當你在外面說'var a =「global」',那麼在函數內部執行'a =「local」',全局變量就變成'local'。如果你添加一個'var',在前面將它視爲它自己的本地'a'變量。 –

+0

@Rrmm - 檢查更新日誌... – Rayon

0

JavaScript有lexical scope,所以在你的例子this總是指的a全球版本,它獲取的第一個片段覆蓋。

由於var在該範圍內定義了一個新變量,因此您不修改全局變量,因此在第二個片段中輸出global

0

首先aglobal,則稱doFoo,該globala設置爲local

我們現在致電fn(),其中調用foo(),這裏this是指當前的執行上下文。這裏的this是指global範圍。

因此提醒local

爲您提供額外的家庭作業:按照類似的邏輯,爲什麼以下警報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