JavaScript的做用域和块级做用域概念理解

任何一对花括号中的语句集都属于一个块,在这之中定义的全部变量在代码块外都是不可见的,咱们称之为块级做用域。javascript

什么是块级做用域呢?

    做用域永远都是任何一门编程语言中的重中之重,由于它控制着变量与参数的可见性与生命周期。讲到这里,首先理解两个概念:块级做用域与函数做用域。java

    任何一对花括号({和})中的语句集都属于一个块,在这之中定义的全部变量在代码块外都是不可见的,咱们称之为块级做用域。编程

    函数做用域就好理解了(*^__^*) ,定义在函数中的参数和变量在函数外部是不可见的。闭包

    大多数类C语言都拥有块级做用域,JS却没有。请看下文demo:编程语言

//C语言 
#include <stdio.h> 
void main() 
{ 
int i=2; 
i--; 
if(i) 
{ 
int j=3; 
} 
printf("%d/n",j); 
}

    运行这段代码,会出现“use an undefined variable:j”的错误。能够看到,C语言拥有块级做用域,由于j是在if的语句块中定义的,所以,它在块外是没法访问的。函数

    而JS是如何表现的呢,再看另外一个demo:spa

function test(){ 
for(var i=0;i<3;i++){ 
} 
alert(i); 
} 
test();

    运行这段代码,弹出"3",可见,在块外,块中定义的变量i仍然是能够访问的。也就是说,JS并不支持块级做用域,它只支持函数做用域,并且在一个函数中的任何位置定义的变量在该函数中的任何地方都是可见的。为了更好理解这一点,请看下面的示例:.net

var scope="global";
function scopeTest(){
  console.log(scope);//a
  var scope="local"
}
scopeTest(); //undefined

    此处的输出是undefined,而不是global,为何呢?这是由于在scopeTest函数中有声明变量scope,尽管它在a语句以后,但对于a语句来讲,变量scope是可见的,且根据局部变量的优先级高于全局变量的原则,JS引擎找到了局部变量scope就不会再去找全局变量scope了,上面的代码等同于:htm

var scope="global";
function scopeTest(){
  var scope;
  console.log(scope);
  scope="local"
}
scopeTest(); //local

    局部变量scope是已被声明的,只是未被赋值,因此打印的是undefined。blog

那么咱们该如何使JS拥有块级做用域呢?

    是否还记得,在一个函数中定义的变量,当这个函数调用完后,变量会被销毁,咱们是否能够用这个特性来模拟出JS的块级做用域呢?看下面这个DEMO:

function test(){ 
(function (){ 
for(var i=0;i<4;i++){ 
} 
})(); 
alert(i); 
} 
test();

    这时候再次运行,会弹出"i"未定义的错误,哈哈,实现了吧~~~这里,咱们把for语句块放到了一个闭包之中,而后调用这个函数,当函数调用完毕,变量i自动销毁,所以,咱们在块外便没法访问了。

    JS的闭包特性is the most important feature((*^__^*) 你们懂的)。(注:原做者称之为闭包,笔者认为这只是个自执行函数。)在JS中,为了防止命名冲突,咱们应该尽可能避免使用全局变量和全局函数。那么,该如何避免呢?不错,正如上文demo所示,咱们能够把要定义的全部内容放入到一个

(function (){ 
//内容 
})();

    之中,这时候,咱们是否是至关于给它们的外层添加了一个函数做用域呢?该做用域以外的程序是没法访问它们的。

 

 经过本文,咱们知道JS没有块级做用域(与C,Java的区别之一);此外,咱们能够经过JS的自执行函数模拟块级做用域。

    本文引自:http://www.jb51.net/article/55435.htm

拓展:bootstarp实例    

 为了让JS具有C或Java语言中类的概念,JS经常使用自执行函数(function(){})();的形式进行模拟,如著名的bootstarp(bootstarp.js):

 

在这个JS中,共用_get,_createClass等4个全局变量,建立了Util,Alert等11个“类”,传递的参数是jQuery($)。

相关文章
相关标签/搜索