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中三种作用域详解(全局,函数,块级)

1.全局变量:声明在函数外部的变量(所有没有var直接赋值的变量都属于全局变量) 2.局部变量:声明在函数内部的变量(所有没有var直接赋值的变量都属于全局变量) JS中变量申明分显式申明和隐式申明。...
  • limu693992297
  • limu693992297
  • 2016年11月25日 09:20
  • 14408

js变量的作用域详解、生存周期,以及一些小细节。

写在前面: 是想写一个闭包的,因为写的比较细,基于篇幅,所以闭包前面关于变量的部分就单独发出来,到时候放个链接引进来,js闭包虽然是一个被讲烂的东西,但其实很多人刚接触这个概念也不太懂,所以希望...
  • OBKoro1
  • OBKoro1
  • 2017年04月29日 13:26
  • 739

深入理解JS中的变量作用域

文章转载http://blog.csdn.net/beijiguangyong/article/details/8301707点击打开链接 在JS当中一个变量的作用域(scope)是程序中定义这个变...
  • bbs375
  • bbs375
  • 2016年09月09日 08:45
  • 2037

js变量作用域

  • 2012年08月28日 11:49
  • 44KB
  • 下载

js变量作用域--变量提升

js的变量和其他语言的变量作用域,有很多相同的地方,但也有很多不相同的地方。尤其是变量提升这个概念。之前还真没听说过这个概念。   先看具体的例子: function test2(){ ale...
  • xuexiaodong2009
  • xuexiaodong2009
  • 2015年05月27日 15:02
  • 1354

理解JavaScript的变量,变量作用域,作用域链

JavaScript的变量,变量作用域,作用域链
  • ganyingxie123456
  • ganyingxie123456
  • 2017年03月05日 22:34
  • 388

JavaScript的作用域和变量对象

变量对象先来说说什么是变量对象,变量对象中又存储了什么东西吧。 JavaScript中的执行环境包括全局执行环境和函数执行环境这两种,每进入到一个执行环境都会创建一个变量对象,这个对象中记录了在当前...
  • VivianHope
  • VivianHope
  • 2015年07月04日 10:46
  • 1278

深入理解JS中的变量作用域

在JS当中一个变量的作用域(scope)是程序中定义这个变量的区域。变量分为两类:全局(global)的和局部的。其中全局变量的作用域是全局性的,即在JavaScript代码中,它处处都有定义。而在函...
  • beijiguangyong
  • beijiguangyong
  • 2012年12月18日 22:27
  • 25810

微信小程序的作用域和模块化 —— 微信小程序教程系列(8)

文件作用域 模块化
  • michael_ouyang
  • michael_ouyang
  • 2017年02月13日 11:32
  • 4061

深入理解JS中的变量作用域

文章转载http://blog.csdn.net/beijiguangyong/article/details/8301707点击打开链接 在JS当中一个变量的作用域(scope)是程序中定义这个变...
  • bbs375
  • bbs375
  • 2016年09月09日 08:45
  • 2037
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:js变量作用域的一些例子
举报原因:
原因补充:

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