众所周知,JavaScript是动态类型语言,比较灵活,经常存在一些使人的头疼的地方。面试
例如:bash
var a = 10 ;
闭包
add()
函数
function add() {
ui
return a + b;
spa
};
code
var b = 1;
cdn
结果输出NaN ;
blog
这就很使人头疼,下面咱们来解释下为何会出现这种状况吧。three
JavaScript是解释型语言,解释一行执行一行,也能够理解为读取一行执行一行(一行一行执行就对了)
var
申明的变量会存在变量提高过程,函数也会存在这种状况 。提高能够分为全局变量,函数提高,和局部变量,函数提高(⚠️注意,变量提高优于函数提高!)
下面咱们来看下题目执行顺序
首先预编译,
变量提高,
var a = undefind;
var b = undefind;
其次函数提高,
function add () {}
变量函数提高完以后开始计算机系统开始读取代码,第一行,解释一行。
首先执行第一行
var a = undefind ; => var a = 10; //解释第一行代码时发现变量被赋值
add(); //解释函数,去找函数
function add () { //执行函数内部函数
return a + b ; //此时 a = 10;b = undefind;
} //结束add()函数,Number ➕ undefind = NaN;
var b = undefind ; => var b = 1; //发现变量 b 被赋值
以上就是预编译和JavaScript代码执行顺序的顺序。
好了,下面咱们来点面试题吧,相信你们也常常被这些面试题坑。
var one = 1 ;
var two = 2 ;
function sum () {
var three = 3 ;
two = two + three;
return one + three
};
var newSum = new Sum();
console.log(newSum);复制代码
相信你们看过前面的讲解就会当即能够想到结果, 没错答案是6 ;
咱们来看下执行顺序吧。
//首先变量,函数提高
var one = undefind;
var two = undefind;
var newSum = undefind;
function sum() {};
//开始读取并解释JavaScript
var one = undefind => var one = 1;
var two = undefind => var two = 2;
function sum () {
// ⚠️ 函数内部也会存在变量和函数提高
var three = undefind; => var three = 3;
/*
two 被从新赋值,这里还有一个知识点,当函数
内部找不到变量,会向上一层找,一直找到window上,
若是找不到就是undefined,因此在函数内存查找two
找不到,会向上一层查找,在全局变量中找到two和one
*/
two = 2 => two = 2 + 3;
return one + two; //one = 1,two = 2, 输出3
}
//函数sum()的值为3,因此 newSum = 3 ;var newSum = undefind; => var newSum = new sum();
console.log(newSum); => console.log(3);
复制代码
var a = 1;
var b = 2;
function add () {
var c = 3;
return a + b;
}
var sum = new add();
console.log(sum);
console.log(c);复制代码
你们能够思考下会打印什么,先来过程吧
//预编译,变量,函数提高
var a = undefind;
var b = undefind;
var sum = undefind;
function add () {};
//读取解释代码
var a = undefind; => var a = 1;
var b = undefind; => var b = 2;
function add () {
var c = undefind; => var c = 3;
return a + b ; => 1 + 2;
}
var sum = undefind; => var sum = new add(); //var sum = 3;
console.log(sum) // 3
//这里涉及到一个新知识点,c属于局部变量,全局变量没法访问访问局部变量
//固然有一种方法能够访问,那就是闭包了😄
console.log(c) // c is not defind;
复制代码
可能你们仍是以为很简单,那咱们在加大难度。
var a = 1 ;
var b = 2;
var i = 0;
function add() {
for (;i < b ; i++) { (function (f) {
console.log(f)
})(i)
};
return a + i;
}
console.log(i);复制代码
这个算是难度加大版本的了,小伙伴们能够思考下,结果是什么
咱们来看下过程
//预编译,变量函数提高 ⚠️ 预编译阶段仅仅只有函数和变量存在提高!
var a = undefind;
var b = undefind;
var i = undefind;
function add() {}
//读取解释JavaScript
var a = undefind; => var a = 1;
var b = undefind; => var b = 2;
var i = undefind; => var i = 0;
function add () {
//在函数内部没法找到 i 与 b 向上一层查找
for(;i < b ; i++) {
//当即执行函数,避免 i 提早变量赋值,
// 一样用let也能够避免这样的事情发生
(function(f){
// 当即执行函数和let造成暂时性死区效果同样,依次
//打印 0 => 1
console.log(f)
})(i)
//等等,你真的觉得执行完了吗?i < b 当这个条件执行完,i被赋值为2,不要忘记这个小细节哦
}
}
console.log(i); // i 被从新赋值,打印2复制代码
因此结果依次为 0 ,1 ,2
固然还能够在难一点,但是楼主飞机误点了,一直在等飞机😭 深圳这该死的 ☁️
有更好的面试题的小伙伴能够子啊下面留言告诉我呦,一同进步