js变量提高与函数提高的详细过程

你们好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新......前端

在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识点,期间也会分享一些好玩的项目。如今就让咱们一块儿进入 Web 前端学习的冒险之旅吧!git

js变量提高与函数提高的详细过程

先来看两个栗子,下面的两段代码分别输出什么?github

// 代码段1
function foo() {
  var a = 1;
  function a() {}
  console.log(a);
}
foo();

// 代码段2
function foo() {
  var a;
  function a() {}
  console.log(a);
}
foo();

答案是:代码段1打印的是1,代码段2打印的是 a() 函数。segmentfault

为何会这样呢?这就涉及到js中的变量提高和函数提高的具体过程了。微信

一、变量的提高

js是怎么建立变量的呢?函数

以下面的代码:学习

var a = 1;
var b = 2;

js在解析上面的代码的时候,其实会按照下面的方式进行解析的:spa

var a;
var b;
a = 1;
b = 2;

因此 js 并非在咱们定义一个变量的时候,声明完成以后当即赋值,而是把全部用到的变量所有声明以后,再到变量的定义的地方进行赋值,变量的声明的过程就是变量的提高。3d

因此咱们看下下面的栗子:code

function foo() {
  var a = 1;
  console.log(a);
  console.log(b);
  var b = 2;
}
foo();

上面的代码在js的眼中是这样解析的:

function foo() {
  var a;
  var b;
  a = 1;
  console.log(a); // 1
  console.log(b); // undefined
  b = 2;
}
foo();

因此输出的 a 的值为1, b的值为 undefined。

变量在声明提高的时候,是所有提高到做用域的最前面,一个接着一个的。可是在变量赋值的时候就不是一个接着一个赋值了,而是赋值的位置在变量本来定义的位置。本来js定义变量的地方,在js运行到这里的时候,才会进行赋值操做,而没有运行到的变量,不会进行赋值操做。

因此变量的提高,提高的实际上是变量的声明,而不是变量的赋值。

二、函数的提高

函数的提高和变量的提高相似,都是提高到做用域的最开始的位置,只不过变量的提高是分两步的,第一步是变量声明的提高,第二步是变量的赋值。而函数的提高是直接将整个函数总体提高到做用域的最开始位置,至关于剪切过去的样子。

三、变量提高和函数提高的顺序

在做用域中,无论是变量仍是函数,都会提高到做用域最开始的位置,不一样的是,函数的提高后的位置是在变量提高后的位置以后的。

举个栗子:

下面的代码输出什么?

function foo() {
  console.log(a);
  var a = 1;
  console.log(a);
  function a() {}
  console.log(a);
}
foo();

上面的代码在js眼中是这样解析的:

function foo() {
  var a;
  function a() {}
  console.log(a); // a()
  a = 1;
  console.log(a); // 1
  console.log(a); // 1
}
foo();

因此从上面的栗子能够看到,变量的提高是在函数提高以前的,可是变量赋值的部分是在js原型到变量定义的位置才给变量赋值的,而函数提高是至关于直接剪切到最前面的。

咱们再看一个更加复杂一点的栗子:

function foo() {
  console.log(a);
  var a = 1;
  console.log(a);
  function a() {}
  console.log(a);
  console.log(b);
  var b = 2;
  console.log(b);
  function b() {}
  console.log(b);
}

foo();

js是这样解析的:

function foo() {
  var a;
  var b;
  function a() {}
  function b() {}
  console.log(a); // a()
  a = 1;
  console.log(a); // 1
  console.log(a); // 1
  console.log(b); // b()
  b = 2;
  console.log(b); // 2
  console.log(b);// 2
}
foo();

最后,注意:只有声明的变量和函数才会进行提高,隐式全局变量不会提高。

下面的栗子中,b不会进行变量提高。

function foo() {
  console.log(a);
  console.log(b); // 报错
  b = 'aaa';
  var a = 'bbb';
  console.log(a);
  console.log(b);
}
foo();

四、参考连接

js变量提高与函数提高的机制: http://www.javashuo.com/article/p-nudwgxqp-eg.html

相关文章
相关标签/搜索