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

而JS是如何表现的呢,再看另一个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 (){
//内容
})();

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

(0)

相关推荐

  • 为什么JavaScript没有块级作用域

    最近在看ES2015 实战,里面有句话是这么说的 JavaScript 中没有块级作用域 可能会对这个问题大家可能有点不理解,先看个例子 var a = [] for(var i = 0; i < 10; i++){ a[i] = function(){ console.log(i); } } a[6](); 我想很多人会觉得这个问题的结果是6,然而很不幸,答案是10.在试试别的呢.a[7]().a[8]().a[8]()结果都是10!! 由于JS在处理primitive的变量的时候,很多时候会

  • 深入理解ES6学习笔记之块级作用域绑定

    众所周知,js中的var声明存在变量提升机制,因此ESMAScript 6引用了块级作用域来强化对变量生命周期的控制 let const 声明不会被提升,有几个需要注意的点 1.不能被重复声明 假设作用域中已经存在某个标识符(无论该标识符是通过var声明还是let.const变量声明),此时再使用let或const关键定声明会抛错 var count=10 let count=20// 此处则会抛出错误,因为同一作用域内不能重复声明 如果当前作用域内嵌另一个作用域,便可在内嵌的作用域中用let声

  • ES6学习教程之块级作用域详解

    前言 众所周知ES5之前javascript语言只有函数作用域和全局作用域,使用var来声明变量,var声明的变量还存在变量提升使人困惑不已.我们先来复习一下ES5的var声明,再对比学习let和const . var var声明之函数作用域和全局作用域. 来段代码体会一下: function getName() { if (1 + 1 === 2) { var name = 'xixi'; } console.log(name); } getName();//xixi 在c或java语言中na

  • ES6使用let命令更简单的实现块级作用域实例分析

    本文实例讲述了ES6使用let命令更简单的实现块级作用域.分享给大家供大家参考,具体如下: let 带来了更简单的块级作用域 1. ES6新增了let命令,用于声明变量.其与var的不同在于,用let声明的变量只在 { } 内有效.这使得我们可以很方便的实现块级作用域,不再使用立即实行函数. { let a=1; var b=2; } console.log(a); //undefined console.log(b); //2 在for循环中使用let可以有效避免全局变量污染. 2. let不

  • Javascript中的作用域及块级作用域

    一.块级作用域的说明 在学习JavaScript的变量作用域之前,我们应当明确几点: a.JavaScript的变量作用域是基于其特有的作用域链的. b.JavaScript没有块级作用域. c.函数中声明的变量在整个函数中都有定义. javascript的变量作用域,与平时使用的类C语言不同,例如C#中的代码: static void Main(string[] args) { if(true) { int number=10; } Console.WriteLine(number); } 这

  • JavaScript使用闭包模仿块级作用域操作示例

    本文实例讲述了JavaScript使用闭包模仿块级作用域操作.分享给大家供大家参考,具体如下: 在阅读这篇文章之前,建议先阅读JavaScript的作用域链以及JavaScript闭包. 正如闭包的定义一样:"闭包指的是有权访问另一个函数作用域中的变量的函数", 闭包最大的意义就在于闭包可以对另一个函数作用域的变量进行访问,由此,闭包可以延伸出一系列的用法. 模仿块级作用域 JavaScript没有块级作用域的概念.这意味着在块语句中定义的变量,实际上是包含在函数中而非语句中创建的.从

  • JavaScript ES新特性块级作用域

    目录 1.块级作用域是什么 2.为什么需要块级作用域 3.与函数声明 前言: 在学习块级作用域之前需要我们对作用域有个了解,所谓的作用域就是代码当中的某个成员起作用的范围. 1.块级作用域是什么 所谓的块级作用域,就是该变量只能在声明时的代码块或者子代码块中使用.在ECMAScript 2015以前的版本中是不存在块级作用域的,而ECMAScript 2015提供的let关键字,使JavaScript出现了块级作用域,示例代码如下所示 /* * 块级作用域只能使用 let 关键字 * let关键

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

    作用域永远都是任何一门编程语言中的重中之重,因为它控制着变量与参数的可见性与生命周期.讲到这里,首先理解两个概念:块级作用域与函数作用域. 什么是块级作用域呢? 任何一对花括号({和})中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域. 函数作用域就好理解了(*^__^*) ,定义在函数中的参数和变量在函数外部是不可见的. 大多数类C语言都拥有块级作用域,JS却没有.请看下文demo: //C语言 #include <stdio.h> void mai

  • 通过函数作用域和块级作用域看javascript的作用域链

    在ES6之前,javascript只有全局作用域和函数作用域.所谓作用域就是一个变量定义并能够被访问到的范围.也就是说如果一个变量定义在全局(window)上,那么在任何地方都能访问到这个变量,如果这个变量定义在函数内部,那么就只能在函数内部访问到这个变量. 全局作用域只要页面没关闭就会一直存在,而函数作用域只有在函数执行的时候才存在,执行完就销毁.且每次执行函数都会创建一个新的作用域. 那么什么是作用域链呢? 在了解作用域链之前,我们先了解一个执行期上下文的概念. 执行期上下文:当函数执行时,

  • JavaScript匿名函数之模仿块级作用域

    匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途. 匿名函数:就是没有函数名的函数. 函数的定义,首先简单介绍一下函数的定义,大致可分为三种方式 第一种:这也是最常规的一种 function double(x){ return 2 * x; } 第二种:这种方法使用了Function构造函数,把参数列表和函数体都作为字符串,很不方便,不建议使用. var double = new Function('x', 'return 2 * x;'); 第三种: var

  • JavaScript块级作用域绑定以及状态提升详解

    目录 前言 作用域/执行上下文 var声明 块级声明 不声明的变量 1.不使用关键字声明变量 2.使用var声明的变量 var声明和块级声明的区别 全局作用域绑定 状态提升 块级绑定的最佳实践 函数声明提升 总结 前言 在ES6之前,JavaScript只有经典的var声明,这给开发者带来了很多的困扰.在ES6出现后,又增加了let和const关键字的声明方式.这里会讲有关变量声明,作用域,状态提升相关知识. 作用域/执行上下文 在JavaScript的世界里,作用域可以分为三种,分别是全局作用

  • 深入理解es6块级作用域的使用

    一.var 声明与变量提升机制 在JavaScript中使用var定义一个变量,无论是定义在全局作用域函数函数的局部作用域中,都会被提升到其作用域的顶部,这也是JavaScript定义变量的一个令人困惑的地方.由于es5没有像其它类C语言一样的块级作用域,因此es6增加了let定义变量,用来创建块级作用域. 我们来看一个var定义变量的示例: function setName(){ if(condition){ var name = 'loho'; console.log(name); }els

  • 解析JavaScript模仿块级作用域

    javaScript 没有块级作用域的概念.这意味着在块语句中定义的变量,实际上是在包含函数中而非语句中创建的,来看下面的例子: function outputNumbers(count){ for (var i=0; i < count; i++){ alert(i); } alert(i); //计数 } 这个函数中定义了一个for 循环,而变量i 的初始值被设置为0. 在Java.C++等语言中,变量i 只会在for 循环的语句块中有定义,循环一旦结束,变量i 就会被销毁.可是在JavaS

随机推荐