全面了解全面了解JavaScript的作用域链的作用域链
是一个非常重要的知识点了,了解了JavaScript的作用域链的话,能帮助我们理解很多‘异常’问题。文中通过示
例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起
学习学习吧
JavaScript的作用域链的作用域链
这是一个非常重要的知识点了,了解了JavaScript的作用域链的话,能帮助我们理解很多‘异常'问题。
下面我们来看一个小例子,前面我说过的声明提前的例子。
var name = 'Skylor.min';
function echo() {
alert(name);
var name = 'mm';
alert(name);
alert(age);
}
echo();
对于这个例子,没有接触过这方面的时候,第一反应是会纠结下,这第一个的name,到底调用全局变量的name,还是函数
内部的name呢,如果调用全局的,可是函数内部也用定义和赋值啊, 如果调用函数内部的局部变量的话,那么他的值是mm
吗?还是引用全局的'Skylor.min'呢?
于是这个小例子就会有这样的错误答案:
Skylor.min
mm
[脚本出错]
其实不然,知道函数内的提前说明,就知道这是不正确的。
undefined
mm
[脚本出错]
应该是这样的,那到底为什么是这个答案呢,提前声明这又是什么呢?一切的一切,涉及到JavaScript的作用域链。
原理原理
首先来说说,JavaScript的作用域的原理:
在JavaScript权威指南中有一句很精辟的描述: JavaScript中的函数运行在它们被定义的作用域里,而不是它们被运行的作用中的函数运行在它们被定义的作用域里,而不是它们被运行的作用
域里。域里。
另外在JavaScript中有个很重要的概念,那就是: 在在JavaScript中,一切皆对象,函数也是。中,一切皆对象,函数也是。
在JS中,作用域的概念和其他语言差不多, 在每次调用一个函数的时候 ,就会进入一个函数内的作用域,当从函数返回以
后,就返回调用前的作用域
JS的语法风格和C/C++类似, 但作用域的实现却和C/C++不同,并非用“堆栈”方式,而是使用列表,具体过程如下(ECMA262中
所述):
任何执行上下文时刻的作用域, 都是由作用域链(scope chain, 后面介绍)来实现
在一个函数被定义的时候, 会将它定义时刻的scope chain链接到这个函数对象的[[scope]]属性
在一个函数对象被调用的时候,会创建一个活动对象(也就是一个对象), 然后对于每一个函数的形参,都命名为该活动对
象的命名属性, 然后将这个活动对象做为此时的作用域链(scope chain)最前端, 并将这个函数对象的[[scope]]加入到scope
chain中.
看个例子吧:
var func = function(lps, rps){
var name = 'Skylor.min';
........
}
func();