学习完后的总结:
Js代码分为两个阶段:编译阶段和执行阶段;
Js代码的编译阶段会找到所以的申明,并用合适的作用域将他们关联起来,这个是词法作用域的核心内容;
包括变量申明和函数声名都会在代码被执行前的编译阶段首先被处理
提升:他们声明操作会提升到执行环境的顶部,复制,逻辑操作符不变;
1.变量声明:
var a = 2;
function foo(){
console.log(a);//undefined
var a = 10;
console.log(a);//10
}
foo();
//等同于
function foo(){
var a;//先声明提升在执行环境的顶部
console.log(a);//undefined
a = 10;
console.log(a);//10
}
foo();
2.函数声明(函数声明和函数表达式两种声明方式)
函数声明:提升会在编译阶段声明和函数体整体都提前到执行环境顶部,所以我们可以在函数声明之前调用这个函数
函数表达式:其实就是变量声明的一种,声明操作会被提升到执行环境顶部,并复制undefined,赋值操作被留在原地等待执行;
函数表达式
baz();//错误
var baz = function(){
console.log(200);
}
//相当于
var baz;
baz();
baz=function(){
console.log(200);
}
3.控制语句
Js中使用{}没有作用域(函数及作用域不存在块级作用域),所以普通块中的声明都会被提升到顶部,所以控制语句对声明的控制就显得完全没有效果
if(false){
var a = 10;
}
console.log(a);//undefined
//想当于
var a;
if(false){
a = 10;
}
console.log(a);//undefined
当为函数声明的时候
console.log(a);//undefined
if(false){
function a(){
console.log(100);
}
}
a();//错误找不到a()函数
console.log(baz);//undefined
if(true){
baz();//200//--------------1
function baz(){
console.log(200);
}
}
console.log(baz);//undefined
if(true){
//baz();//错误
var baz = function(){
console.log(200);
}
}
//按道理如果因为if()无作用域所以a()为全局函数应该会输出为100;但是却没有说明了,当出现判断区域的时候,可能函数也只是提升出了一个指针函数名,值为undefined,在判断区域块中吧函数提升到了判断区域的顶部,所以全局外找不到a()函数,--------1的值才是200.
4.优先级别
提升操作会优先进行函数声明,然后是变量,重复的变量申明会被忽视只剩下赋值操作,重复的函数声明会被进行覆盖;
foo();//200被覆盖
function foo(){
console.log(100);
}
function foo(){
console.log(200);
}
//第二种
console.log(foo);//值为(ƒ foo(){console.log(100);}相当于一个指针)函数声明的提升高于变量声明,所以不等于100.
function foo(){
console.log(100);
}
var foo = 100;
以上是我学习完后的理解,如果大佬们有不用意见可以告诉我,我在给予更改