2016-08-30 71 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