var a = 1;
var b = function(){
console.log(a); // function a(){}
a = 10;
console.log(a); //10
return;
function a(){} //声明提升
}
b();
console.log(a); //1 为什么是这个数?
最后打印出来的a值,不应该是10吗?为什么是1呢?
var a = 1;
var b = function(){
console.log(a); // function a(){}
a = 10;
console.log(a); //10
return;
function a(){} //声明提升
}
b();
console.log(a); //1 为什么是这个数?
最后打印出来的a值,不应该是10吗?为什么是1呢?
我的理解,function a(){},相当于在局部作用域b函数中定义了一个a函数,a=10是对b作用域中的a赋值,此时局部作用域b中的a从函数变成一个常量。至始至终没有改变b外作用域中的a=1的值。
其实,你已知道声明提升,只是最后被代码搞乱了而已,把它整理成下面这样,就一目了然了,全局的变量a就没被改变过:
var a = 1;
var b = function(){
var a = function (){};
console.log(a);
a = 10;
console.log(a);
return;
//function a(){}
}
b();
console.log(a);
声明有有两种,且仅有两种,var 以及 function ,所以调用了 b()就相当于在里面开了块动态内存,重新声明了个变量 a,这两个a 所处的内存位置都不一样,自然不是同一个了,b(){}里面的a,根本就不是外面的a,而且把b()调用执行了一次,那块内存就消失了。故尔,他们说外面的为全局变量,里面的就是局部变量,就是这个道理了!
既然都理解了function a(){}
是函数的提前声明,怎么会不理解输出1呢,一开始在函数内部声明了一个局部变量a,由于执行上下文的特性缘故,执行函数时a变量就是一个函数了a=10
只是将你内部的局部变量更改了,也就是把你的那个function
改变为了'number'类型的变量,执行函数后,这个局部变量就会被销毁。
var a = 1;
var b = function(){
console.log(a);
a = 10;
console.log(a);
return;
function a(){}
}
b();
console.log(a);
你也知道 b
函数里的 function a(){}
提升了,所以 b
函数里所有对 a
的操作其实都是重新赋值
这里说的 a
是局部的,是 b
函数内的
这里说的 a
是局部的,是 b
函数内的
这里说的 a
是局部的,是 b
函数内的
所以最后一句 console.log(a)
是打印全局的 a
,也就是一开始初始化的 1
很明显 最下面那个console是在Window作用域下,那window下的a是多少呢,是1。函数里面的执行顺序是这样的,function a(){},先声明了方法a,然后重新赋值了a=10,这个a是对方法a的赋值。
作用域啊!你那函数b中由于由于声明提升a最初是函数,然后又变成数字。但它只有在调用b函数时执行一次,然后就从内存中清楚了。一点也没有影响全局的a,所以a值还是1。
我觉得你可能忽略的一个知识点:函数声明同时也创建了一个和函数名相同的变量。这样一来函数作用域内部的执行顺序如下:
var b = function() {
var a;
function a(){};
console.log(a);//a()
a=10;
console.log(a);//10
}
13 回答12.8k 阅读
7 回答1.9k 阅读
3 回答1.1k 阅读✓ 已解决
2 回答1.2k 阅读✓ 已解决
6 回答872 阅读✓ 已解决
6 回答1k 阅读
2 回答1.3k 阅读✓ 已解决
“函数声明同时也创建了一个和函数名相同的变量”
参考:MDN函数——Function构造函数vs函数声明vs函数表达式
所以,函数作用域中的代码执行顺序就相当于下面这样了:
这表明在b函数作用域内又声明了一个变量
a
,覆盖了全局变量a
,发生的一切都是在函数作用域内。b函数外的
console.log(a);
访问的自然是全局变量a
了,因为它访问不到b函数作用域内的变量。关于变量声明提升VS函数声明提升,顺序谁在前谁在后参考变量声明提升VS函数声明提升