上一章:JS的数据类型 传送门:https://segmentfault.com/a/11...javascript
好!话很少少,咱们就开始吧。对变量提高和函数声明的理解,能让你更清楚容易的理解,为何你的程序报错了~哈哈哈css
咱们前端的代码通常就三个部分组成html + css +js,通常呢咱们的JS又会放在最后执行。html
执行上下文:
所谓的执行上下文,就是JS代码执行的环境。前端
Javascript中代码的运行环境分为如下三种:java
全局上下文 - 这个是默认的代码运行环境,一旦代码被载入,引擎最早进入的就是这个环境。segmentfault
函数上下文 - 当执行一个函数时,运行函数体中的代码。闭包
Eval上下文 - 在Eval函数内运行的代码。函数
这个和做用域有点像。
每次调用一个函数将会建立一个新的执行上下文会,被添加到做用域链的顶部。
做用域和执行上下文之间最大的区别是: 执行上下文在运行时肯定,随时可能改变;做用域在定义时肯定,永远不会改变。学习
其实上面那些看看就好,直接看代码吧。this
JS代码在执行以前会先全局中变量提高、函数声明。在函数中变量提高、函数声明(this、函数参数也会提高,函数中的变量提高的范围是这个函数的内部)
变量提高:变量赋值的过程:声明---初始化---赋值
举例子:函数内部的变量提高(全局的变量提高也是同理)
function fn(){ console.log(x);//undefined var x = 1; console.log(x);//1 } fn();
这里咱们从针对变量x来解说:
1.在执行fn时,为fn建立一个执行环境。(fn函数的执行上下文,也就是在fn这个函数范围内)
2.找到fn函数执行上下文中(fn函数范围内),全部用var声明的变量。
3.将这些变量初始化为undefined。
4.开始执行代码。
5.把1赋值给变量x。
至关于以下这样:
function fn(){ //把用var声明的变量,提高到顶部,并初始化为undefined var x =undefined; //开始执行代码。 console.log(x);//undefined //把1赋值给变量x。 var x = 1; console.log(x);//1 } fn();
函数声明:
cat();//123 function cat(){ console.log(123); } cat();//123
1.找到全部用function声明的变量,并在环境中建立这些变量。
2.将这些变量初始化并赋值为function(){xxx}
3.在环境中从上往下开始执行代码。
至关于以下这样:
//1.找到全部用function声明的变量,并在环境中建立这些变量。 //2.将这些变量初始化并赋值为function(){xxx} var cat = function (){ console.log(123); } //3.在环境中从上往下开始执行代码。 cat();//123 cat();//123
这个就是函数声明,在代码执行前,会把function提到顶部。因此若是不行代码,代码块里即便有错误也不会报出来,只有执行时才会运行代码内部东西。
看到这里应该有个初步了解了,那么来看看下面的。加点难度,加深了解。
<!DOCTYPE html> <html> <head> <title>3543541</title> </head> <body> <script type="text/javascript"> fn2();//undefined fn();//undefined function fn(){ console.log(g); } fn();//undefined console.log(g);//undefined var g = 'global'; console.log(g);//global fn2()//global function fn2(){ console.log(g); } fn2()//global fn();//global </script> </body> </html>
为何fn中的globle拿不到呢?而fn2的globle能拿到值呢?
运用上面学习的知识来分析一波。
上面代码在执行前,会通过变量提高、函数声明,因此在准备执行前的代码是这样的:
//函数声明会在最最顶端 var fn = function (){ console.log(g); } var fn2 = function (){ console.log(g); } //执行函数和变量按照相对位置排列 //执行的相对位置不能变,这3个是在变量g以前执行的就要一直在g以前执行 fn2(); fn(); fn(); var g = undefined; console.log(g);//undefined var g = 'global'; console.log(g);//global //执行的相对位置不能变,这3个是在变量g以后执行的就要一直在g以后执行 fn2(); fn2(); fn();
这里咱们能够总结出一点规律:
1.函数声明会在最最顶端
2.变量提高,只是在本身的范围内提高
3.执行的相对位置不能变和变量按照执行上下文以前的相对位置排列。
4.函数执行时,按照执行位置查找变量做用域只会向上查找。
下一回:变量做用域与闭包