js中的作用域与变量提升和函数提升

一、什么是提升(Hosting)?

// 引擎会在解释JavaScript代码之前首先对其进行编译,

**// 编译过程中的一部分工作就是找到所有的声明,**

**// 并用合适的作用域将他们关联起来,这也正是词法作用域的核心内容。**

**// 简单说就是在js代码执行前引擎会先进行预编译,**

**// 预编译期间会将变量声明与函数声明提升至其对应作用域的最顶端。**

二、变量提升

       a = 2;

       var a;

       console.log(a)                



       console.log(a);      

           var a = 2

**// 按照JS代码的执行顺序应该是从上到下一行行的执行的,真的是这样吗??其实这不是完全正确的。**

**// 正确的思路是,包括变量,函数在内的所有声明都会在任何代码在执行前首先被处理。**

**// 当你看到var a = 2 时你可能会理解成这是一个声明,**

**// 但JS在执行时实际上会将其看成两个声明 var a 和 a = 2**

**// 第一个var a 是在代码的编译阶段执行的。**

**// 第二个赋值声明 a = 2 会被留在原地等待执行阶段来执行**

   在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),

只有全局作用域和函数作用域。变量提升即将变量声明提升到它所在作用域的最开始的部分。

        console.log(good); // undefined

        var good = 'good';

        console.log(good); // good

       // function fn() {

       //     console.log(a); // undefined

       //     var a = 'aaa';

       //     console.log(a); // aaa

       // }

       // fn()

之所以会是以上的打印结果,

    是由于js的变量提升,实际上上面的代码是按照以下来执行的:

  var good; // 变量提升,全局作用域范围内,此时只是声明,并没有赋值

   console.log(good); // undefined

  good= 'good

  console.log(good); // 打印出good

       function fn() {

        var a; // 变量提升,函数作用域范围内

        console.log(a);

       a = 'aaa';

           console.log(a);

       }

       fn();

三、函数提升

**//   js中创建函数有两种方式:函数声明式和函数字面量式。**

**// 只有函数声明才存在函数提升!注意:使用匿名函数的方式不存在函数提升,**

**// 因为函数名称使用变量表示的,只存在变量提升。**

  例一

      console.log(f1);     // function f1() {}

       console.log(f2); // undefined

       function f1() { }//

       var f2 = function () { }//函数表达式,匿名函数

   // 之所以会有以上的打印结果,

   // 是由于js中的函数提升导致代码实际上是按照以下来执行的:


   function f1() { } // 函数提升,整个代码块提升到文件的最开始

       console.log(f1);

       console.log(f2);

       var f2 = function () { }

**例二:**

   foo();

   function foo(){

  console.log("aaa");

  }

结果输出: aaa  原理:函数声明提升 (函数声明提升直接把整个函数提到执行环境的最顶端)

相当于:

function foo(){

console.log("aaa");

}

foo();

变量提升只提升函数名 而函数提升会提升整个函数  注意:函数提升在变量提升上面。

**例三:**

foo();

var foo = function(){

console.log("aaa");

}

运行结果是: foo is not a function

相当于;

var foo;

console.log(foo);  //undefined

foo(); //foo is not a function

foo = function(){

console.log("aaa");

}

上面代码输出undefined 是因为变量提升后并没有赋值因此输出undefined

输出foo is not a function 原因是:js解析遇到 foo()时会默认当做函数来解析

**例四:**

console.log(foo);

var foo=10;

console.log(foo);

function foo(){

console.log(10);

}

console.log(foo);

输出为:

相当于:

function foo(){

console.log(10);

}

var foo;

console.log(foo);

foo=10;

console.log(foo);

console.log(foo);

函数提升在变量提升上面,第一个console.log(foo);为什么会输出函数题呢,原因在于 var foo; 并未有赋值只是声明,因此他会调用上面的值

总结:关于变量提升,一定要注意细心思考一下,还有就是要牢记,函数提升在变量提升之上

你可能感兴趣的:(js中的作用域与变量提升和函数提升)