JS 变量声明提升(Hoisting)

来源:互联网 发布:成都学院软件邀请赛 编辑:程序博客网 时间:2024/06/11 00:35

变量声明提升(Hoisting)

JavaScript 会提升变量声明。这意味着 var 表达式和 function 声明都将会被提升到当前作用域的顶部。

bar();var bar = function() {};var someValue = 42;test();function test(data) {    if (false) {        goo = 1;    } else {        var goo = 2;    }    for(var i = 0; i < 100; i++) {        var e = data[i];    }}

上面代码在运行之前将会被转化。JavaScript 将会把 var 表达式和 function声明提升到当前作用域的顶部。

// var 表达式被移动到这里var bar, someValue; // 缺省值是 'undefined'// 函数声明也会提升function test(data) {    var goo, i, e; // 没有块级作用域,这些变量被移动到函数顶部    if (false) {        goo = 1;    } else {        goo = 2;    }    for(i = 0; i < 100; i++) {        e = data[i];    }}bar(); // 出错:TypeError,因为 bar 依然是 'undefined'someValue = 42; // 赋值语句不会被提升规则(hoisting)影响bar = function() {};test();

没有块级作用域不仅导致 var 表达式被从循环内移到外部,而且使一些 if 表达式更难看懂。

在原来代码中,if 表达式看起来修改了全局变量 goo,实际上在提升规则被应用后,却是在修改局部变量

如果没有提升规则(hoisting)的知识,下面的代码看起来会抛出异常ReferenceError

// 检查 SomeImportantThing 是否已经被初始化if (!SomeImportantThing) {    var SomeImportantThing = {};}

实际上,上面的代码正常运行,因为 var 表达式会被提升到全局作用域的顶部。

var SomeImportantThing;// 其它一些代码,可能会初始化 SomeImportantThing,也可能不会// 检查是否已经被初始化if (!SomeImportantThing) {    SomeImportantThing = {};}

译者注:在 Nettuts+ 网站有一篇介绍 hoisting 的文章,其中的代码很有启发性。

// 译者注:来自 Nettuts+ 的一段代码,生动的阐述了 JavaScript 中变量声明提升规则var myvar = 'my value';  (function() {      alert(myvar); // undefined      var myvar = 'local value';  })();  

名称解析顺序

JavaScript 中的所有作用域,包括全局作用域,都有一个特别的名称 this 指向当前对象。

函数作用域内也有默认的变量 arguments,其中包含了传递到函数中的参数。

比如,当访问函数内的 foo 变量时,JavaScript 会按照下面顺序查找:

  1. 1. 当前作用域内是否有 var foo 的定义。
  2. 2. 函数形式参数是否有使用 foo 名称的。
  3. 3. 函数自身是否叫做 foo
  4. 4. 回溯到上一级作用域,然后从 #1 重新开始。
0 0
原创粉丝点击