请写出弹出值,并解释为什么。
~function () {
alert(a);
a();
var a = function () {
console.log(1);
}
function a() {
console.log(2);
}
alert(a)
a();
var c = d = a;
}();
alert(d);
alert(c);
请写出弹出值,并解释为什么。
~function () {
alert(a);
a();
var a = function () {
console.log(1);
}
function a() {
console.log(2);
}
alert(a)
a();
var c = d = a;
}();
alert(d);
alert(c);
包括打印和alert的值如下:
1、
function a() {
console.log(2);
}
2、2
3、
function a() {
console.log(1);
}
4、1
5、
function a() {
console.log(1);
}
原因: var c = d = a;
从右向左执行,d=a
,d没有使用var声明,是一个全局变量,方法外部可访问。
6、报错,原因:c是函数内部的变量,外部访问不到的,外部变量c是undefined。
其它的就不一一解释原因了,本质就是变量提升和函数声明提升的问题。
1: function a() {
console.log(2);
}
2,3 var a = function () {
console.log(1);
}
4: 报错
因为 函数提升优于变量提升 且 变量提升只声明不赋值, 局部变量作用于局部
词法分析:
0:函数的在运行的瞬间,生成一个活动对象(Active Object)就是所谓的AO
1:分析参数
1-1:函数接收参数,添加到AO的属性上面,值全部都是undefine,如AO.age=undefine
1-2:接收实参,形成AO对应的属性值
2:分析变量声明,如var age,
2-1:如果AO上还没有age属性,则添加AO 属性,值是undefine
2-2:如果AO 上面已经有了age属性,则不做任何操作。
3:分析函数的声明,例如funcion a(){},
3-1: 则把函数赋给AO.a,如果数据属性已经存在,则要被现在的新的值覆盖
4:执行 (赋值操作是执行中的过程);
放在这道题里就是:
分析参数:
即时函数没有参数;
分析变量:
函数内部 AO= {a:undifined,c:undefined} 全局 AO= {c:undefined}
分析函数的声明:
function a() {console.log(2);}
因为AO中已经存在a,a被覆盖为function a() {console.log(2);}
执行:
alert(a);//a就是函数声明 function a() {console.log(2);}
a();//执行a -->2
var a = function () {console.log(1);} a被赋值为新函数
function a() {console.log(2);} //已经分析过跳过
alert(a) // 弹出a 为新赋值的 function () {console.log(1);}
a(); 执行a 打印 1
var c = d = a; // c d 赋值为function () {console.log(1);}
即时函数执行完,向下执行
alert(d); //作用域中有d 为function () {console.log(1);}
alert(c); //作用域中没有c 报错c is not defined
关于这段代码,我关注两个问题:
1、alert
出什么?
2、对于
~function () {
function code
}();
这段语句为何能作为函数执行起来?
问题一的话,上面几位朋友说得很清楚,关于问题二就是通过 ~ ! ||
等操作符使得解释器将函数声明能当做表达式来处理。
详见这里描述得很详细
主要考点就是函数和变量声明的提升顺序
~function () {
alert(a) //function a(){ //coding }
a();//console.log(2)
var a = function () {
console.log(1);
}
function a() {
console.log(2);
}
alert(a)//a = function () { //coding }
a();//console.log(1)
var c = d = a;
}();
alert(d);//a = function () { //coding } d为全局变量
alert(c) //ReferenceError: c is not defined c是局部变量
~function (){
function a() {
console.log(2);
}
var a;
var c;
alert(a)
a()
a = function (){
console.log(1)
}
alert(a)
a();
d = a
c = d;
}()
console.log(d)
console.log(c)
个人感觉这样更加合理一点吧。
中间那段代码等同于如下
function a() {
console.log(2);
}
var a;
alert(a);
a();
a = function () {
console.log(1);
}
alert(a)
a();
var c = d = a;
首先了解变量提升和函数声明提升
则
function a() {
console.log(2);
}是函数声明,会提升到代码顶部
从上到下依次顺序:
1.弹出
function a() {
console.log(2);
}
2.后台打印出:
2
3:弹出
function () {
console.log(1);
}
4.后台打印出
1
5,6.都弹出
function () {
console.log(1);
}
这个问题其实是考你对JS预解析和闭包的理解,
function () {
alert(a); // 因为JS是单线程,而前面没有声明a所以这里报错
a(); //这里也会报错因为也没有声明
var a = function () { // 这里是一个函数表达式
console.log(1);
}
function a() { // 这里是声明一个函数
console.log(2)
}
alert(a) // 这里会打印一个函数,因为var声明的a被function声明的a函数层叠掉了
a(); // 这里当然是函数调用 打印2
var c = d = a; // 这里切记 并不是 var a , b ,c ; 所有d没有声明
}(); //这是一个闭包也是一个自调用函数
alert(d); //这里会报错
alert(c); // 这里会弹出一个函数体
8 回答4.6k 阅读✓ 已解决
6 回答3.4k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
5 回答6.3k 阅读✓ 已解决
4 回答2.2k 阅读✓ 已解决
4 回答2.8k 阅读✓ 已解决
3 回答2.4k 阅读✓ 已解决
实际上,这段代码是这么跑的:
参考:hoisting