我们首先看一段代码:
console.log(smh);
var smh = "全局";
function fn() {
console.log(smh);
var smh = "函数";
}
fn();
大家认为会输出什么呢?还是会直接报错呢?我们来看看结果吧。
1.undefined 2.undefined
两个输出都是undefined。为什么呢?这就要从js中变量的提升和函数作用域来说起了。
首先我们定义了两个变量。都名为smh,其中一个位于全局作用域中,另一个位于函数作用域中。
大家会认为第一个输出会报错,因为变量的声明在输出在后,第二个输出会打印出“全局”,因为第二个变量声明也是声明于打印之后,这就要从js中的变量的提升说起了。
在js引擎在解释代码之前会进行编译,编译的时候,就会找到所有的变量声明,把所有的变量的声明(不赋值)提升到各自作用域的顶端。
比如上述的代码就会变成如下形式:
var smh;
console.log(smh);
smh = "全局";
function fn() {
var smh;
console.log(smh);
smh = "函数";
}
fn();
看到这里,大家应该就明白了为什么两个输出都是undefined了把。
我主要说说函数里面的输出为什么也是undefined,这就跟作用域链有关了。
上述代码一共有两个执行环境,以下是“Javascript高级程序设计”中对于作用域的解释
当代码在一个环境中执行时,会创建变量对象的一个作用域链( scope chain)。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象( activation object)作为变量对象。活动对象在最开始时只包含一个变量,即 arguments对象(这个对象在全局环境中是不存在的)。作用域链中的下一个变量对象来自包含(外部)环境,而再下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。标识符解析是沿着作用域链一级一级地搜索标识符的过程。搜索过程始终从作用域链的前端开始,然后逐级地向后回溯,直至找到标识符为止(如果找不到标识符,通常会导致错误发生)
因为函数有自己的执行环境,js的变量提升,把变量提升了这个函数的最顶端。所以自然也是输出undefined了,
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。