網上找了兩個經典的例子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
歡迎轉載,但請註明出處,謝謝!