javascript - js 作用域的问题

查看:83
本文介绍了javascript - js 作用域的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

if (false) {
 function c1() {console.log(1);}
}
c1();


if (false) {
 var c2 = function() {console.log(1);}
}
c2();

请问各位大哥,解释下c1c2的区别

解决方案

js是个很鬼的语言,所以你需要有自戳双目的勇气。
这个问题涉及到js的解析阶段、执行阶段、变量提升,详细的需要自己去查资料了,简单理解可以如下。

js中,函数声明式在执行前会被解析,你可以理解为,function c1这个函数声明已经被提到了执行之前定义,所以你写成这样子也是可以执行的

c3();
if (false) {
 function c3() {console.log('c3');}
}

上面这么写是能够输出'c3'的。


然而赋值表达式(函数赋值表达式),则是执行时才会运行。只有在进入了if语句之后,开始执行赋值表达式时,匿名函数的赋值才声明。
运行c2报错为TypeError,因为c2声明了,但是没有定义,它只是一个可怜的undefined

if (false) {
 var c5 = function c6() {
  console.log(5);
  console.log(c6);
 }
}
c5();
c6();

上面这个例子里c5是undefined,c6会报错not defined
变量声明var是被解析了的,所以c5是声明了,没有定义。
这里又有一个点。
当条件为false时,赋值表达式是没有执行的。
当条件为true是,赋值表达式是执行了的。
这两种条件中c6都是not defined,但是意义是不一样的。
false时确实是未定义,但是true时是因为js对函数的命名处理。赋值的命名函数,函数名对外是不可见的,但是对内可见。

总的来说,可以理解为js有两次解释执行:

第一次:解析加载变量声明,函数声明,对函数的参数赋值
第二次:给变量赋值,执行函数

另送黑暗圣经地址:
MDN Functions

参考
函数作用域中定义在后面的变量能被前面的表达式访问到吗?

PS: 之前答案写错的一个代码,爆栈了。

if (true) {
 var c5 = function c6() {
  console.log(5);
  c6(); // stack overflow
 }
}
c5();
c6();

这篇关于javascript - js 作用域的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆