js作用域以及作用域链的理解

以前一直以为自己对作用域和作用域链了解的比较清晰,直到最近碰到一个问题的时候,才发现自己是真的傻逼了,具体问题的应用场景就不在这里说了,下面我将简单举例说明下;
示例1:
var a=20;
function b1(){
console.log(a);
};
function b2(){
var a=40;
b1();
};
b2();
如果能够正确的写出最后的结果的朋友们请忽略本题,如果和我一样,想象的结果和实际的运行结果不一致的话,那么请接着往下看。
对于上面的题目,我自己一开始没咋经过大脑,或者说经过了大脑,但是基于对作用域和作用域链的理解不是那么的深刻,所以做错了这题。
上面的示例中,首先是经过全局作用域,这个相信大家应该没什么问题, 然后在全局作用域中,先进行预解析,此时会有一个变量对象,该变量对象中有a属性和b1,b2声明的函数。之后代码开始进入到执行步骤,在执行步骤中,遇到了a变量赋值以及执行函数b2,此时控制器进入到了b2的函数作用域中, 同样,先进行预解析,此时变量函数中会有变量a,然后在进入到代码执行阶段,在代码执行阶段,遇到了可执行代码b1();则进入到函数b1中, 进入到b1中时,遇到了console.log(a)了,那么首先在函数b1中找变量a,此时会发现没有变量a,那么,将在函数b1的父作用域中找变量a,而函数b1的父作用域是全局作用域,在全局作用域中, 找到了a=20;则此时最后的输出结果是20;所以经过示例1我们可以看到, 函数的作用域是定义的时候就已经确定了,而不是在调用的时候确定的
以上就是一个大致的思路了,下面请大家继续看下一个示例:
var a=20;
function b1(){
console.log(this.a);
};
function b2(){
this.a=40;
b1();
};
b2();
同理,非常了解作用域和作用域链以及this指向的同学请路过即好,那么上面的代码最终的输出结果是什么呢?原因是什么。
如果此时看了第一个示例解释的同学可能会说,答案是20;那不是和第一题一样嘛,那么恭喜你,同学,成功答错了,为什么呢?
在上面的示例中, 正常的作用域是和示例1一样的,但是这里又涉及到了另外一个点,es5中this的指向性问题,这里就不针对this的指向性做详细的解释了,关于this的指向问题的话,有一个结论就是,this的确定是在函数运行时候确定的。可能有的同学会比较迷糊了,那么我们还是针对示例2来看:
在示例2中,b1函数是调用了this.a,而this的指向又是在b1调用的时候确定的,所以我们需要到b2中去看了,在b2中指向b1的时候,此时this才有了一个真正的指向对象了,在这里,此时b1中的this指向的是b2,那么很显然,既然指向b2,那么this.a也就是指向了b2中的a了, 所以最后的结果就是40
个人的描述能力比较差,如果有什么描述不清楚的地方,欢迎来喷。

你可能感兴趣的:(js作用域以及作用域链的理解)