js变量作用域的一些例子

原创 2016年09月05日 10:38:10

本来想要在“作用域”这个专题上自己总结出一些东西的,结果想了好久都没有形成一个固定的思路,也不想贸然拷贝网上的说法。所以,还是先记录几个容易犯错的小例子,以后再来形成总结吧。


1、“变量声明提升”

例子1:

var x = 'global';

function f1() {
    console.log(x);
}

function f2() {
    console.log(x);

    /*
        这里x的声明让f2的函数作用域中拥有了x这个变量,所以以后访问x的时候,不会再沿着作用域链上搜索
        而上面那一句把x打印出来的时候,x只是声明了但没有初始化
        所以输出undefined
    */
    var x = 'local';
}

f1();   // global
f2();   // undefined

例子2(摘自360校招笔试题):

var a, b;

(function () {
    console.log(a);// undefined
    console.log(b);// undefined

    var a = b = 0;// (1)

    console.log(a);// 0
    console.log(b);// 0
})();

console.log('window', a);// window undefined
console.log('window', b);// window 0

解释:这里最关键的是理解清楚语句(1)处的执行情况,这个语句做的工作实际上是:

b = 0;         // (2)
var a = b;     // (3)

   语句(2)执行之后,在匿名函数的scope中并没有找到b的声明,故这里修改的是全局scope中的b,也就是让window.b赋值为0了。所以,在语句(1)之前,window.b的值是undefined,在(1)之后,window.b就是0了,就算出了匿名函数,window.b也是0。
   语句(3)声明了a,那么匿名函数中所有出现的a都是本scope中的a,而不是window.a。所以,在a声明了却还没初始化的时候,a的值为undefined,初始化之后就是0了。而出了匿名函数之后,打印的是window.a的值,自然是undefined了。


2、js的函数作用域是静态作用域

var x = 'global';

function f1() {
    console.log(x);
    // 此函数被调用的时候,x在这里没有声明,所以会沿着作用域链开始寻找
    // 然而,Js的作用域是“静态”作用域,也就是说在声明函数的时候就可以确定而不必等到运行时
    // 所以,这里的作用域链为:f1-->window,所以输出window.x的值“global”
}

function f2() {
    var x = 'f2';

    // f2在函数内部调用f1
    f1();
}

f1();   // global
f2();   // global(并非f2)

如果把作用域的嵌套结构改成下面的样子,结果就会不一样:

var x = 'global';

function f1() {
    console.log(x);
}

function f2() {
    var x = 'f2'; // (1)

    // 将函数f1声明在f2内部,这样,作用域链就变成:
    // f1 --> f2 --> window
    // 所以输出的是f2的x即'f2'
    function f1() {
        console.log(x);
    }

    f1();
}

f1();   // global
f2();   // f2

举一反三,如果把上面(1)这一句放在f1被调用的后面,自然就输出“undefined”了:

var x = 'global';

function f1() {
    console.log(x);
}

function f2() {
    //var x = 'f2'; // (1)

    // 将函数f1声明在f2内部,这样,作用域链就变成:
    // f1 --> f2 --> window
    // 所以输出的是f2的x即'f2'
    function f1() {
        console.log(x);
    }

    f1();

    var x = 'f2'; // (1)
}

f1();   // global
f2();   // undefined

3、不加var修饰的变量,并不一定是window下的变量

例如下面这个小程序,很容易以为输出的是“global”,然而并不是:

function f1() {

    function f2() {
        x = 'global';   // (2)

        // 解释:
        // 这里x没有var关键字修饰,但也不一定就是指window.x
        // 根据作用域链:f2 --> f1 --> window
        // 首先,在f2中,并没有x的声明,所以去f1找
        // 然后,在f1中,语句(1)声明了有x,所以在这一层停止搜索x了
        // 也就是说,语句(2)修改的是f1函数作用域中的x
        // 所以最终,输出window.x的值是undefined
    }

    f2();

    var x = 10; // (1)
}

f1();
console.log(window.x);  // 结果:undefined
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

js变量作用域

  • 2012-08-28 11:49
  • 44KB
  • 下载

javascript变量作用域

  • 2013-07-25 20:48
  • 18KB
  • 下载

js变量作用域

变量作用域 “一个变量的作用域表示这个变量存在的上下文。它指定了你可以访问哪些变量以及你是否有权限访问某个变量。” 变量作用域分为局部作用域和全局作用域。 局部变量(处于函数级别的作...

变量作用域

  • 2015-10-15 10:48
  • 460B
  • 下载

js变量以及其作用域详解

一、变量的类型   Javascript和Java、C这些语言不同,它是一种无类型、弱检测的语言。它对变量的定义并不需要声明变量类型,我们只要通过赋值的形式,可以将各种类型的数据赋值给同一个变量。...

PHP中的变量作用域

  • 2010-03-26 15:47
  • 338KB
  • 下载

深入理解变量作用域

js变量作用域var的区别

“JavaScript对变量作用域的规定是: - 变量在全局声明,或者在代码的任何位置隐士声明(不用var),则该变量在全局可见 - 变量在函数内显示申明(使用var),则在该函数内可见” ...

PHP中的变量作用域.pdf

  • 2010-03-05 11:28
  • 338KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)