JavaScript Hoisting

Hoisting是javascript的一个特性,翻译成中文不知道叫什么合适,声明提前?

来看下面这个例子:

// we know this wouldn't work (assuming there
// is no notDefined global variable)
function example() {
  console.log(notDefined); // => throws a ReferenceError
}

// creating a variable declaration after you
// reference the variable will work due to
// variable hoisting. Note: the assignment
// value of `true` is not hoisted.
function example() {
  console.log(declaredButNotAssigned); // => undefined
  var declaredButNotAssigned = true;
}

// The interpreter is hoisting the variable
// declaration to the top of the scope.
// Which means our example could be rewritten as:
function example() {
  var declaredButNotAssigned;
  console.log(declaredButNotAssigned); // => undefined
  declaredButNotAssigned = true;
}

 

No1,直接使用了一个没有声明过的变量,因此报错

No2,在console.log之后声明了变量并赋值,打印出来是undefined

No3,在console.log之前声明变量,之后赋值,打印出来仍然是undefined

产生这个效果的,正是Hoisting的作用,用一句话总结就是:

变量声明会被解析器提到对应作用域的最前面,而变量赋值不会。

 

第二个例子

function example(){
  console.log(anonymous);// => undefined
  anonymous();// => TypeError anonymous is not a function
  var anonymous=function(){
      console.log('anonymous function expression');
  };
}

对于匿名函数表达式,变量名会被提前,而函数赋值不会

 

第三个例子

function example() {
  console.log(named); // => undefined

  named(); // => TypeError named is not a function

  superPower(); // => ReferenceError superPower is not defined

  var named = function superPower() {
    console.log('Flying');
  };
}

// the same is true when the function name
// is the same as the variable name.
function example() {
  console.log(named); // => undefined

  named(); // => TypeError named is not a function

  var named = function named() {
    console.log('named');
  }
}

可见,对于命名的函数表达式,也只是将变量名提前,而不是函数名或者函数体

 

第四个例子

function example() {
  superPower(); // => Flying

  function superPower() {
    console.log('Flying');
  }
}

函数声明,会将该声明和函数体都提前

再回看我之前写过的一篇文章,阿里面试题,答案就很简单了

 

var b=2;
function b(){
  alert('b');
}
b();

根据Hoisting,可以写成下面这样

var b;
function b(){
  alert('b');
}
b=2;
b();

变量声明和函数声明都被提前,而b后来又被赋值为2,因此报错,number is not a function