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

作用域

作用域永远都是任何一门编程语言中的重中之重,因为它控制着变量与参数的可见性与生命周期。说到这里我们需要理解两个概念:块级作用域与函数作用域。

函数作用域

这个应该好理解,函数作用域就是说定义在函数中的参数和变量在函数外部是不可见的。

大多数类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的语句块中定义的,因此,它在块外是无法访问的。

块级作用域

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

正如我们举的C语言的例子,大多数类C语言都是有块级作用域的,那么在JavaScript又有什么不同呢?

我们一起看看这个JavaScript的demo:

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

运行这段代码,弹出"3",可见,在块外,块中定义的变量i仍然是可以访问的。也就是说,JS并不支持块级作用域,它只支持函数作用域,而且在一个函数中的任何位置定义的变量在该函数中的任何地方都是可见的。

那么我们该如何使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 (){ 
//内容 
})();

之中,这时候,我们是不是相当于给它们的外层添加了一个函数作用域呢?该作用域之外的程序是无法访问它们的。

Happy hacking!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Petrichor的专栏

python: 装饰器 / 迭代器 / 生成器

写在 被装饰函数 的 正上方 。可提前注明接下来的介绍内容,例如@property、@classmethod、@staticmethod。

782
来自专栏奇点大数据

Scala语言学习笔记一

Scala是一门小众的语言,但是作者因为工作原因要以Spark作为工作中的一个重心,而Spark采用了Scala语言编写,于是萌生了认真学习Scala的念头,在...

3554
来自专栏柠檬先生

Angularjs基础(十)

ng-blur  描述:规定blur 事件的行为       实例:当输入框失去焦点的(onblur)时执行表达式:         <input ng...

1925
来自专栏技术翻译

JVM体系结构的解释

每个Java开发人员都知道字节码将由JRE(Java运行时环境)执行。但许多人并不知道JRE是Java虚拟机(JVM)的实现,它分析字节码,解释代码并执行它。作...

882
来自专栏前端架构与工程

【翻译】JavaScript内存泄露

我们在进行JavaScript开发时,很少会考虑内存的管理。JavaScript中变量的声明和使用看起来是一件很轻松的事,底层的细节处理交给浏览器去做就好了。 ...

1996
来自专栏C/C++基础

申明与定义的区别

C++编码过程中,我们经常谈及“定义”和“声明”,二者是编程过程中的基本概念。我们需要使用一个变量、类型(类、结构体、枚举、共用体)或者函数时,我们需要提前定义...

812
来自专栏C/C++基础

函数申明对函数模板实例化的屏蔽

C++语言引入模板机制后,函数调用的情形显的比C语言要复杂。当发生一次函数调用时,如果存在多个同名函数,则C++编译器将按照如下的顺序寻找对应的函数定义。 ...

642
来自专栏小筱月

jQuery 事件绑定 和 JavaScript 原生事件绑定

jQuery 中提供了四种事件监听绑定方式,分别是 bind、live、delegate、on,

902
来自专栏pangguoming

Angular2 -- 生命周期钩子

指令和组件的实例有一个生命周期:新建、更新和销毁。 每个接口都有唯一的一个钩子方法,它们的名字是由接口名加上 ng前缀构成的。比如,OnInit接口的钩子方法...

822
来自专栏软件开发 -- 分享 互助 成长

C++ STL之list容器的基本操作

由于list和vector同属于序列式容器,有很多相同的地方,而上一篇中已经写了vector,所以这一篇着重写list和vector的不同之处和特有之处。 特别...

2477

扫码关注云+社区