JavaScript 变量做用域

一. 变量声明

变量用var关键字来声明,以下所示:javascript

var num;
var a,b;
var name = "ting";
var i=0, j=1, k=2;

用var关键字申明的变量是永久的,用delete运算符删除不起做用。html

var i = 2;
delete i;
console.log(i);   // 2

k = 3;
delete k;
console.log(k);  // 报错:ReferenceError: k is not defined.

JavaScript变量是松散类型的,能够用来保存任何数据类型。而且还可在修改变量的值时改变变量的类型。前端

var answer = 10;
answer = "The answer is: " + 10;
console.log(answer);                 // 10
console.log( typeof answer);          // string

 

二. 变量做用域

变量的做用域是程序中定义这个变量的区域。函数内部声明的变量只在函数内部起做用。声明局部变量必定要使用var关键字声明。java

在函数内部,局部变量做用域高于同名全局变量。segmentfault

var i = 99;
function foo() {
     var i = 100;
    console.log(i);   // 100(使用局部变量)
}
foo();
console.log(i);       // 99(使用全局变量)

声明局部变量未使用var关键字,该变量会暴露在全局环境中,与现有的全局变量冲突。以下代码中,函数内部的变量a未使用var关键字,与全局环境中的a冲突,在全局环境中调用a。函数

var a = 5;
function foo() {
    a = 10;
    b = 15;
    console.log(a);   // 10
    console.log(b);   // 15
}
foo();
console.log(a);       // 10
console.log(b);       // 15

变量在未声明的状况下被初始化,会被添加到全局环境。spa

var add =  function(a,b) {
     var sum = a + b;
     return sum;
}
var res = add(2,3);
console.log(res);        // 5
console.log(sum);        // ReferenceError: sum is not defined

var add =  function(a,b) {
    sum = a + b;
     return sum;
}
var res = add(2,3);
console.log(sum);        // 5

JavaScript执行代码时,会建立一个上下文执行环境,全局环境是最外围的环境。每一个函数在被调用时都会建立本身的执行环境,当函数执行完,当前执行环境被销毁。code

每一个执行环境都有一个与之关联的做用域链。在执行代码时,JavaScript引擎会经过搜索执行环境的做用域链来解析变量和函数名这样的标识符。 解析过程从做用域链的前端开始,向上逐级查询与给定名字匹配的标识符,一旦找到标识符,搜索过程就中止,不然继续沿做用域链向上搜索,一直搜索到全局对象。若是没有搜到,则认为该标识符未定义。标识符在做用域链中的位置越深,查找和访问它的时间越长,因此尽量使用局部变量。htm

全局环境只能访问在全局环境中定义的变量和函数,不能直接访问局部环境中的任何数据。对象

 

三.  没有块级做用域

JavaScript中没有块级做用域,举个例子。若是JavaScript中有块级做用域的话,控制台输出的应该是undefined。但实际上控制台输出的是100,这是为何呢? 缘由在于:没有块级做用域,变量i没有被销毁,所以还能访问到这个变量。

for( var i=0; i<100; i++) {
     // todo
}
console.log(i);    // 100

JavaScript中存在函数做用域。当foo函数执行完毕后,函数内的变量将被销毁,所以控制台报错。

function foo() {
     var bar = "fn";
}
foo();
console.log(bar);   // 报错:ReferenceError: bar is not defined.

函数做用域模拟块级做用域。

( function() {
     for( var i=0; i<100; i++) {
         // todo
    }
})();
console.log(i);    //报错:ReferenceError: bar is not defined.

再看一例:局部变量a在整个foo函数内部都有定义的,隐藏了全局变量a。但第一个console在变量初始化以前,因此其值为undefined。

var a = 8;
var foo =  function() {
    console.log(a);      // undefined
     var a = 5;
    console.log(a);      // 5
};
foo();


四. 未赋值的变量和未定义的变量

未赋值的变量值为undefined,而使用未定义的变量会引发错误。

var a;
console.log(a);   // undefined
console.log(b);   // ReferenceError: b is not defined


五. 垃圾收集(garbage collection)

JavaScript具备自动垃圾收集机制,Javascript解释器能够检测到什么时候程序再也不使用一个对象,就把它所占用的内存释放。

 

 

 

时间:2014-10-22

地点:合肥

引用:http://wlog.cn/javascript/javascript-variable-scope-chain.html 

        http://segmentfault.com/blog/liangyi/1190000000692129

相关文章
相关标签/搜索