js作用域相关问题

先上代码

function a() {
    var temp = 10;
    function b() {
        console.log(temp); // 10
    }
    b();
}
a();
function a() {
    var temp = 10;
    b();
}
function b() {
    console.log(temp); // 报错
}
a();

模模糊糊有个作用域的概念,但是无法清楚明白的说出来,请大佬指点~

*打印出a函数的原因是将变量和函数取为同名了,现在已修改

阅读 3.5k
8 个回答

第一段代码相信没啥问题,函数b执行是能取到其父函数a作用域下的变量a

第二段由于函数a和函数b是同级函数,变量a是在函数a的作用域下,且没有全局作用域下的变量a的声明,所以报错。

第二种,怎么会是报错呢?不太明白题主的报错是什么意思,a是一个函数,输出函数不会报错

调用函数时函数内调用的变量会在本函数内或定义函数的作用域向外找

在定义函数的作用域找而非调用的作用域:

function a(){
    console.log(b);
}
let b = 10
{
    let b = 1;
    a();//10
}

当调用b的时候,b会在本函数内找a,没有向外找,去定义b的作用域(全局)找a,这时a是全局函数找到了,然后输出a

globalContext={

AO:{
    a: function,
    b: function,
},
scopeChain: [globalContext.AO],
this: globalContext.this

}

aContext = {

AO:{
    a = 10
},

scopeChain: [globalContext.AO, aContext.AO],
this: globalContext.this

}

bContext = {

AO:{
},
scopeChain:[globalContext.AO, bContext.AO],
this: gloabalContext.this

}

执行上下文栈,
b的AO中找不到变量a,会顺着作用域链向上爬,在gobal中找到函数a,打印出来
ESstack = [globalContext, aContext, bContext]

问题太基本,并且很宽泛,建议看看《JavaScript高级程序设计》或者《You Don't Know JS》的相关章节,以及 sf 有很多相关文章。

简单介绍作用域:作用域说白了就是一套规则,一套存储变量,并可以访问变量的规则。作用域类型可以分为:词法作用域、函数作用域以及块作用域。涉及到词法作用域就不能不提闭包这个非常有用而又神秘的概念。当某个函数可以记住并访问所在的词法作用域,且在当前词法作用域之外执行时就产生了闭包。
当然作用域不止这些东西。因为javascript其实最难的就三个东西:作用域、原型、异步,要彻底理解还是需要花点时间慢慢跑几个demo才行的。

讲完作用域,在回头看看你的代码:
上面的函数b打印a之所以报错,是因为变量a是在函数a中定义的,b是没有这个变量的,所以就报错了。

我试了下 没报错啊 打出来的是函数 a。求大佬指点下

es6之前javascript只有全局作用域和函数作用域,没有块级作用域。要么就是全局,要么就是函数作用域。函数可以访问父级函数的变量,反过来则不行。函数里的变量只能在函数内部访问,外部则不行。第一个a函数里面有一个b函数,实际上这是一个闭包,a函数外部不能访问a函数内部的a变量。第二个,函数a和函数b都在全局作用域下,a函数不能访问b函数内部的变量,b函数也不能访问a函数内部的变量,所以才会报错。

不会报错,b函数中的a打印出来是a函数

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题