网上找了两个经典的例子javascript
var foo = 1; function bar() { if (!foo) { var foo = 10; } alert(foo); } bar(); // 10
var a = 1; function b() { a = 10; return; function a() {} } b(); alert(a);// 1
在JavaScript中,函数、变量的声明都会被提高(hoisting)到该函数或变量所在的scope的顶部。即——JavaScript的变量提高。html
javascript中一个名字(name)以四种方式进入做用域(scope),其优先级顺序以下:java
名字声明的优先级如上所示。也就是说若是一个变量的名字与函数的名字相同,那么函数的名字会覆盖变量的名字,不管其在代码中的顺序如何。但名字的初始化倒是按其在代码中书写的顺序进行的,不受以上优先级的影响。git
(function(){ var foo; console.log(typeof foo); //function function foo(){} foo = "foo"; console.log(typeof foo); //string var foo; })();
function test() { foo(); // TypeError "foo is not a function" bar(); // "this will run!" var foo = function () { // function expression assigned to local variable 'foo' alert("this won't run!"); } function bar() { // function declaration, given the name 'bar' alert("this will run!"); } } test();
变量的提高(Hoisting)只是其定义提高,而变量的赋值并不会提高。
再来看一个例子,下面两段代码实际上是等价的:github
function foo() { if (false) { var x = 1; } return; var y = 1; } function foo() { var x, y; if (false) { x = 1; } return; y = 1; }
建立一个函数的方法有两种:
一种是经过函数声明function foo(){}
另外一种是经过定义一个变量var foo = function(){}express
function test() { foo(); // TypeError "foo is not a function" bar(); // "this will run!" var foo = function () { // function expression assigned to local variable 'foo' alert("this won't run!"); } function bar() { // function declaration, given the name 'bar' alert("this will run!"); } } test();
var foo
首先会上升到函数体顶部,然而此时的foo
为undefined
,因此执行报错。而对于函数bar
, 函数自己也是一种变量,因此也存在变量上升的现象,可是它是上升了整个函数,因此bar()
才可以顺利执行。segmentfault
本文参考自:
http://www.cnblogs.com/damonlan/archive/2012/07/01/2553425.html
http://www.javashuo.com/article/p-mlexwjqf-cp.html
https://segmentfault.com/a/1190000005794611函数
做者博客:pspgbhuthis
做者GitHub:https://github.com/pspgbhucode
欢迎转载,但请注明出处,谢谢!