Javascript作用域和变量提升笔记

最近读了一篇有关js作用域和变量升级的文章,对其理解更加渗透,传送门在此。

总结知识点如下:

  1. 在代码运行前,函数声明和变量定义通常会被解释器移动到其所在作用域的最顶部

     需要注意:变量的上升(Hoisting)只是其定义上升,而变量的赋值并不会上升

  2. JavaScript是一种函数级作用域,if中并没有独立维护一个模块。

      C,C++,C#和Java都是块级作用域语言,js想实现类似的块级作用域效果是用闭包。

       但ES6中let声明存在块级作用域。但是let不像var那样会发生“变量提升”现象。所以,变量一定要在声明后使用,否则报错。

  3. 构建函数 function foo () {} 与 var foo = function () {}的区别:

    function foo () {} 函数声明,函数本身也是变量,变量上升,上升整个函数

    var foo = function () {} 函数表达式,是将一个匿名函数赋值给一个变量,变量上升,只上升var foo; 然后是个赋值的过程

掌握了这些知识点就可以理解这几个例子了😃:

1. 

var foo = 1;
function bar() {
    if (!foo) {
        var foo = 10;
    }
    alert(foo);
}
bar();

alert的是10,等同于以下代码

var foo;
foo = 1;
function bar() {
    var foo;
    if (!foo) {
        foo = 10;
    }
    alert(foo);
}
bar();

2.

var a = 1;
function b() {
    a = 10;
    return;
    function a() {}
}
b();
alert(a);

alert的是1, 等同于以下代码

var a = 1;
function b() {
    function a() {}
    a = 10; // 这时候的赋值,其实是把函数b里面函数a变成了数值
    return;
}
b();
alert(a);

3.

function test() {
    foo(); // TypeError "foo is not a function"
    bar(); // "this will run!"
    var foo = function () { 
        alert("this won't run!");
    }
    function bar() { 
        alert("this will run!");
    }
}
test();

foo()报错,bar()可以执行,是因为,其代码相当于

function test() {
    var foo;
    function bar() {
        alert("this will run!");
    }
    foo();
    bar();
    foo = function () {
        alert("this won't run!");
    }
}
test();

4.

console.log(foo); // 输出undefined
console.log(bar); // 报错ReferenceError

var foo = 2;
let bar = 2;

5.

function f1() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}

 

posted @ 2019-02-21 16:12  簌大侠  阅读(224)  评论(0编辑  收藏  举报