浅谈JavaScript变量声明提高

前段时间阿里实习生内推,一面就被刷了,也是郁闷。今天系统给发通知,大体意思就是内推环节不足以了解彼此,还能够参加笔试,因而赶忙再投一次。官网流程显示笔试时间3月31日,时间快到了,开始刷题。网上搜了一下去年题目,我擦,第一题就不会(伤心中...),继续往下看,第四题也不会。。。好嘛,搜答案吧。搜了一个多小时的博客,结合本身的理解,写下了这篇博文。。。javascript

2014年阿里巴巴前端工程师笔试题目1:html

var v = "Hello world";
	(function() {
		console.log(v);
		var v = "I love you";
		bar();
		foo();
		 function bar(){
		 	console.log("this is bar!");
		 }
		 
		 var foo = function() {
		 	console.log("this is foo!");
		 };
		 
	})();
请写出上面的运行结果并说出背后的理由。
题目4:指出一下代码的运行结果,并解释为何。
function bar() {
	return foo;
	foo = 10;
	function foo() {}
	var foo = 11;
}

alert(typeof bar());

其实上面两道题考察的核心是同样的,即JavaScript变量声明的相关概念,以前了解过一点,但了解的不是太深。前端

要谈JavaScript变量声明,就离开不了做用域的问题。而JavaScript中没有相似C,JAVA等语言中的块级做用域。如:java

#include <studio.h>
int main() {
	int i = 1;
	printf("d%",i); //1
	if(1){
		int i = 2;
		printf("d%",i); //2
	}
	printf("d%",i); //1
	return 0;
}
而JavaScript中相应的输出结果就变成了1,2,2。缘由就是JavaScript中只有函数做用域,这也是致使JavaScript中一个经典问题的缘由,即循环遍历DOM节点绑定事件后触发问题。如:

window.onload = function() {
	var oLi = document.getElementsByTagName("li");
	for(var i=0,len=oLi.length;i<len;i++){
		oLi[i].onclick = function() {
			alert(i);
		};
	}
};
扯得有点远,下面仍是说一下JavaScript语言中的变量声明提高的问题吧。

一、当访问函数内的变量时,JavaScript会按照下面顺序查找:浏览器

(1)语言级别:默认在所用做用域下的this,arguments前端工程师

(2)传入参数:函数命名的参数,做用域是当前函数体。函数

(3)函数声明:如题1中的function bar() {} 与 题4中的function foo() {}this

(4)变量声明:如var v  与 var foo
二、变量声明与函数声明常常被JavaScript引擎隐式的提高到当前做用域的顶部。spa

2.一、变量声明:.net

局部做用域内声明变量须要加关键词var,即

function a(){
	console.log(typeof b);
	var b = 3;
}
实际上被解释成

function a(){
	var b;
	console.log(typeof b);
	b = 3;
}

而若是不加关键词var,则默认引用全局做用域内的相关变量,浏览器中即window做用域。如图:


因此若是你能理解下面代码的运行结果是a=10,则说明对变量声明部分已经足够了解。

<span style="white-space:pre">	</span>var a = 1;
	function b() {
		if(!a) {
			var a = 10;
		}
		alert(a);
	}
	b();
2.二、函数声明:咱们都知道函数命名有两种方式,一种是函数声明方式function bar() {} 另一种就是经过赋值语句的方式,即函数声明表达式var foo = function() {};

而这两种函数命名方式虽然都会出现变量声明提高的现象,但第一种提高现象会包含函数体部分一块儿被提高,即整个函数bar被提高。而第二种则只是简单的变量提高(想象一下将赋值语句后面的函数代码改成基本变量,如数字5,则和上一步所说的变量声明部分彻底吻合)。

所以得出以下结论:

(1)JavaScript中声明语句会被提高,而赋值语句不会被提高。

(2)函数声明提高优先于变量声明提高。
如今你应该能明白阿里笔试题1中输出结果是undefined this is bar! error:undefined is not a function. 题4中的结果是function.

特此感谢如下博主的精彩博文:

harmony的专栏《2014年阿里巴巴前端工程师笔试题》

浪迹天涯《JavaScript中变量提高------Hoisting》

Nomospace《翻译——JavaScript中的变量做用域与变量声明提高》

相关文章
相关标签/搜索