美文网首页
js - 声明提升

js - 声明提升

作者: 16manman | 来源:发表于2019-03-22 17:53 被阅读0次

Js代码分为两个阶段:编译阶段和执行阶段

我们习惯将var a = 2;看作一个声明,而实际上JavaScript引擎并不这么认为。它将var a和a = 2当作两个单独的声明,第一个是编译阶段的任务,而第二个则是执行阶段的任务。

这意味着无论作用域中的声明出现在什么地方,都将在代码本身被执行前首先进行处理。可以将这个过程形象地想象成所有的声明(变量和函数)都会被“移动”到各自作用域的最顶端,这个过程被称为 提升

声明本身会被提升,而包括函数表达式的赋值在内的赋值操作并不会提升。

1. 变量声明提升

Js编译器会把变量声明看成两个部分: 声明操作(var a) 和 赋值操作(a=2)

声明操作在编译阶段进行,声明操作会被提升到执行环境的顶部,值是undefined(表示未初始化),赋值操作会被留在原地等待执行阶段

  • 来一个例子:
console.log(name);  //undefined
var name = 'aman';

//相当于
var name;
console.log(name);  //undefined
name = 'aman';
  • 再来一个例子:
var name = 'aman1';
function getName(){
  console.log(name );  //undefined
  var name = 'aman2';
  console.log(name );  //aman2
}
getName();

//相当于
var name = 'aman1';
function getName(){
  var name;
  console.log(name );  //undefined
  name = 'aman2';
  console.log(name );  //aman2
}
getName();
2. 函数声明提升

定义函数有两种方式:

  • 函数声明
  • 函数表达式

1. 函数声明: 函数声明提升会在编译阶段把声明和函数体整体都提前到执行环境顶部,所以我们可以在函数声明之前调用这个函数

foo(); //foo
function foo(){ console.log('foo') } 

2. 函数表达式:其实就是变量声明的一种,声明操作会被提升到执行环境顶部,并赋值undefined。赋值操作被留在原地等到执行。

foo();  //报错:TypeError: foo is not a function
var foo = function(){ console.log('foo') } 

//相当于
var foo;
foo();
foo = function(){ console.log('foo') } 
3. 控制语句

Js中使用函数级作用域,不存在块级作用域。所有普通块中的声明都会被提升到顶部,所以控制语句对声明的控制就显得完全没有效果

if(false){
  var name = 'aman';
}
console.log(name);  //undefined

//相当于
var name;
if(false){
  name = 'aman';
}
console.log(name);  //undefined
4. 函数优先

提升操作会优先进行函数的声明
函数会首先被提升然后才是变量,重复的变量声明会被忽略,只剩下赋值操作,多个函数声明可以进行

声明的顺序是这样的:

  1. 找到所有的函数声明,初始化函数体,如有同名的函数则会进行覆盖
  2. 查找变量声明,初始化为undefined,如果已经存在同名的变量,就什么也不做直接略过
foo();  //b
function foo() { console.log("a"); }
function foo() { console.log("b"); }
var foo = 100;
console.log(foo);  //100

//相当于
//编译阶段:
function foo() { console.log("a"); }
function foo() { console.log("b"); }  //覆盖上边的声明
// var foo; //忽略

//执行阶段:
foo();  //b
foo = 100;
console.log(foo); //100
注意: 尽量避免在控制语句内使用函数表达式声明函数,如下
  • 一个特别的例子
console.log(foo); // (早期的浏览器会输出 b,现在是 undefined)
var a = true;
if (a) {
    function foo() { console.log("a"); }
} else {
    function foo() { console.log("b"); }
}

相关文章

  • js声明提升

    1.声明在前还是赋值在前 直觉上告诉我们js代码执行是从上而下一行一行执行的,但实际上这种思路是不完全正确的以下代...

  • js声明提升

    块级作用域块级作用域是指花括号内的每一段代码都具有各自的作用域,而javascript没有块级作用域。javasc...

  • js - 声明提升

    Js代码分为两个阶段:编译阶段和执行阶段 我们习惯将var a = 2;看作一个声明,而实际上JavaScript...

  • 变量提升和函数提升

    JS不像C语言,C语言是先声明后使用,否则会报错。但JS中,有变量提升现象,可以先使用后声明。 JS存在变量提升,...

  • 变量声明提升

    变量声明提升是JS中一个基础的问题,同时也是对JS词法作用域认识的一个提升。在JS面试题中,关于变量声明提升的问题...

  • JS变量声明提升和函数声明提升

    JS代码分为两个阶段:编译阶段和执行阶段; 编译阶段:会找到所有的声明,并用合适的作用域将它们关联起来,这是词法作...

  • js变量声明提升

    1.变量的定义 可以使用var定义变量,变量如果没有赋值,那变量的初始值为undefined 2.变量作用域 变量...

  • 05 JS 声明提升

    关于编译器,引擎会在解释 JS 代码之前首先对其进行编译。编译阶段的一部分工作就是找到所有的声明,并用合适的作用域...

  • js变量声明提升与函数表达式

    1.变量声明提升 js引擎会把变量声明与函数声明都提升到当前函数的顶部。eg: js引擎编译为 2.函数表达式 对...

  • js面试题

    1、js 数据类型 基本数据类型 引用数据类型 2、js 变量和函数声明的提升 在js中变量和函数的声明会提升到最...

网友评论

      本文标题:js - 声明提升

      本文链接:https://www.haomeiwen.com/subject/efprvqtx.html