一起来了解JavaScript的变量作用域

目录
  • 1.变量作用域的分析
  • 2.var关键字
  • 3.let和const关键字
  • 4.var、let和const的对比
  • 总结

1.变量作用域的分析

首先,我们先研究一下JavaScript的变量作用域,研究作用域,我们不按照常规的文章那样解释概念,而是先给一个小demo,吊一下大家的胃口

var a = 1;
var b = 2;
function pomp(){
    alert(a);
    alert(b);
    b = 2;
    alert(b);
    var a = 3;
    alert(a);
}
pomp();

如果你的答案是对的,那么你对JavaScript的作用域的理解已经是中等偏上了,可能有一些复杂的作用域你没有掌握,但是简单的开发已经没有问题了;如果你不知道答案,那么下面我就以这个例子为引,介绍一下JavaScript的变量作用域问题

首先,如果有编程基础的同学,一定知道对于任何的编程语言,都有局部变量和全局变量的概念:全局变量的作用范围是全局的;而局部变量往往在一个部分被定义和使用,在这个部分之外,它的空间就会被回收,我们就无法再使用它。常见的局部变量出现的地方有:for循环、函数体、代码块。

这些“局部”里,局部变量的优先级是大于全局变量的,这是什么意思呢?我们再用一个小demo来解释一下:

var a = 1
function pomp() {
    var a = 2
    alert(a)
        }
pomp()
alert(a)

也就是说,我们在局部和全局都有一个变量a,那么在局部,脚本解释器会优先从最近的位置开始寻找,最近的位置,当然会有局部>大于全局的效果,于是第一个弹窗弹出的是2,第二个才是1。

介绍完了局部变量和全局变量,我们再回到最开始的那个demo的问题:

var a = 1;
var b = 2;
function pomp(){
    alert(a);
    alert(b);
    b = 2;
    alert(b);
    var a = 3;
    alert(a);
}
pomp();

显然,这里的问题是,我们明明已经给a声明为全局变量,并同时给a赋值了,那为什么会打印a为undefined呢?这就是JavaScript的另一个特点,就是解释器在一行一行解释代码之前,会给变量划好它们的作用域:

最开始,a和b都被声明并定义为全局变量,a有值1,b有值2;此时,我们定义了一个函数pomp(),在函数内部,我们又创建了一个局部变量a,这时候,按照刚才的分析,此时离得最近的其实应该是局部变量a,这就解释了为什么第一次alert(a)不是弹出1,但是还是没有解释undefined。

undefined的原因是这样的:在解释器解释代码之前,按照其他编程语言的叫法,我们称这个时期是预编译时期,在预编译时期,由于函数体内也声明和定义了变量a,于是自然地函数体内的a被划归到了局部变量a,即我们可以认为已经执行了一句:var a,但是由于这是预编译时期,并没有执行var a = 3,因此此时我们可以理解为,只是执行了 var a,而a = 3是在后面才会执行,因此这是undefined的原因

最后针对第一开始的demo做一个图片,帮助大家理解JavaScript变量作用域

并附带一句总结:

当使用var关键字时,在局部或者全局中的任何位置,当某个变量被声明后,无论是之前的哪个地方,都可以使用这个变量,只是会显示undefined。

2.var关键字

最初的JavaScript,只有var这个关键字,因此上面的作用域讲解,说白了是针对的var关键字,那么对于var关键字,这里就不再多做赘述,而是给一个小demo理解一下:

alert(a)
var a = 3
alert(a)

不过避免一些朋友从这里才开始看起,我还是再复述一下:

var关键字声明的变量,只要在局部/全局的任何一个地方被声明,那么在其他的地方,即使没有被声明,由于在预编译阶段该变量已经被声明,于是它也是存在的,只是会显示undefined,也就是未定义,而后当执行到var a = 3,它被定义了一个值3。

顺便简单唠一下变量的声明与定义的区别

  • var a;这句话叫声明变量a
  • a = 3;这句话叫定义变量a
  • var a = 3;这句话叫声明变量a,并给a定义为3

讲完了var,其实作用域的难点也基本上结束了,但是由于是一篇完整的文章,下面对两种新的JavaScript变量声明关键字进行介绍:let和const它们的作用域与var略有不同

3.let和const关键字

首先,我们还是先来一个demo:

alert(a)
let a = 3
alert(a)

哎嘿,大家点击之后,是不是啥也没有啊,这可不是我在恶作剧,而是确实是什么也没有,原因是,它报错了(hahaha):

好家伙,同样的写法,为啥var不报错,let就报错了呢?(注意,这里用const是一样的,const和let的作用域是相同的,也即用const一样会报错!)

原因是,大家苦var久矣,这个let关键字,就是更符合我们的思维逻辑的一种变量的声明方式,在let的作用域中:

一个变量只会在它被声明之后才可以使用,而不是像var一样,在任何地方只要有声明,那么在前面的地方也可以用!

最后,我们简单介绍一下const,const在let的基础上,多了一个唯一性的概念:

const变量一经定义,就不能再修改它的值了,适合定义一些特定的常量,例如:

const pi = 3.14

const e = 2.7

const的作用域与let相同!

4.var、let和const的对比

一口气看完了三个关键字,我们最后再简单梳理一下吧,在梳理之前,先上一个demo:

 function demo() {
            for (var i = 1; i < 10; i++) {
                //
            }
            alert(i)
            for (let j = 1; j < 9; j++) {
                //
            }
            alert(j)
        }
        demo()

大家看到这里似乎又有点小疑惑,因为我们知道for循环是一个局部,那么局部的变量i和j,在for循环的外面,理应不存在才对但是很显然,我们如果核对了会发现,弹窗弹出了一个10,也就是说i此时值仍然保留为10,而j确实和我们想的一样,是不存在的,它也确实报错了:

那为啥会出现这种情况呢?原因是var关键字声明的局部变量,会在整个大的局部退出时,才会回收内存,也就是说for循环虽然也是一个局部,但是这个局部是属于function这个大局部,因此才会出现仍然存在i,但是let显然又一次达到了我们的预期!

关键字 作用域 值的特点
var 变量在局部/全局任何地方被声明,在对应的局部/全局的其他任何地方都可以直接使用(甚至在声明之前使用),但是使用时若未定义,则出现undefined。 可以反复修改
let 变量只能在被声明语句的后面才可以使用。 可以反复修改
const 变量只能在被声明语句的后面才可以使用。 不可修改

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!      

(0)

相关推荐

  • JS中作用域以及变量范围分析

    变量作用域 js作为一门脚本语言,他与c,java这些语言是不相同的. 全局变量 在js中声明全局变量,有下面几种方式: 1.在函数外通过var来声明. var test ="hello"; console.log(test); function a(){ test="xx"; console.log(test); } a(); console.log(test); 结果: hello xx xx 这种方式通过声明的变量在任何地方都可进行修改和使用. 2.在函数中隐

  • javascript 的变量、作用域和内存问题

    javascript 的变量.作用域和内存问题 (一)JavaScript变量可以用来保存两种类型的值:基本类型值和引用类型值.基本类型的值源自以下5种基本数据类型:Undefined.Null.Boolean.Number和 String.基本类型值和引用类型值具有以下特点: 1.基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中: 2.从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本: 3.引用类型的值是对象,保存在堆内存中: 4.包含引用类型值的变量实际上包含的并不是

  • JavaScript中变量的作用域详解

    一.变量的分类 在JavaScript中变量分为两种: 全局变量 局部变量 二.变量的作用域 1.局部变量的作用域 局部变量:在函数内部定义的变量称为局部变量,其作用域为该函数内部,在该函数外部不能被访问.看下面的例子: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" co

  • JavaScript变量作用域_动力节点Java学院整理

    在JavaScript中,用var申明的变量实际上是有作用域的. 如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量: 'use strict'; function foo() { var x = 1; x = x + 1; } x = x + 2; // ReferenceError! 无法在函数体外引用变量x 如果两个不同的函数各自申明了同一个变量,那么该变量只在各自的函数体内起作用.换句话说,不同函数内部的同名变量互相独立,互不影响: 'use stric

  • js 作用域和变量详解

    一.说起变量的提升呢,首先我们先看一段简单的代码 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <script> var v = 'hello world'; alert(v); </script&

  • JavaScript的变量作用域深入理解

    在学习JavaScript的变量作用域之前,我们应当明确几点: a.JavaScript的变量作用域是基于其特有的作用域链的. b.JavaScript没有块级作用域. c.函数中声明的变量在整个函数中都有定义. 1.JavaScript的作用域链 首先看下下面这段代码: 复制代码 代码如下: <script type="text/javascript" language="javascript"> var rain = 1; function rain

  • 一起来了解JavaScript的变量作用域

    目录 1.变量作用域的分析 2.var关键字 3.let和const关键字 4.var.let和const的对比 总结 1.变量作用域的分析 首先,我们先研究一下JavaScript的变量作用域,研究作用域,我们不按照常规的文章那样解释概念,而是先给一个小demo,吊一下大家的胃口: var a = 1; var b = 2; function pomp(){ alert(a); alert(b); b = 2; alert(b); var a = 3; alert(a); } pomp();

  • 深入解析JavaScript中的变量作用域

    在学习JavaScript的变量作用域之前,我们应当明确几点: •JavaScript的变量作用域是基于其特有的作用域链的. •JavaScript没有块级作用域. •函数中声明的变量在整个函数中都有定义. 1.JavaScript的作用域链首先看下下面这段代码: 复制代码 代码如下: <script type="text/javascript"> var rain = 1; function rainman(){ var man = 2; function inner()

  • javascript 变量作用域 代码分析

    代码清单1-1 展示javascript的变量作用域的例子 //设置全局变量foo,并置为"test" var foo = "test"; //在if块中 if(true){ //将foo置为'new test' var foo = "new test"; } //如我们所见,现在foo等于'new test'了 alert(foo == "new test"); //创建一个会修改变量foo的新函数 function tes

  • javascript变量作用域使用中常见错误总结

    今天在rainweb的博客上,看到了这篇非常好的文章,觉得非常有必要分享出来,相信大家认真读完这篇文章,对js作用域的理解又会上升到一个新的台阶. 前言:javascript里变量作用域是个经常让人头痛抓狂的问题,下面通过10++个题目,对经常遇到又容易出错的情况进行了简单总结,代码样例很短很简单 题目一 复制代码 代码如下: var name = 'casper'; alert(name); //毫无疑问地输出:casper 题目二 复制代码 代码如下: alert(name); //报错:对

  • Javascript 变量作用域 两个可能会被忽略的小特性

    也许有些高手早已知道了,但是我觉得这两个东西还是有一些价值的,所以拿到这里和大家分享一下吧. 有如下代码: 复制代码 代码如下: <script type="text/javascript" > function test() { with (location) { var temp = "an url"; } alert(temp); } test(); </script> 调用这个函数会输出什么呢? 也许会认为它会弹出undefined,

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

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

  • 不同浏览器javascript变量作用域的处理方法

    1.关于prototype:这里prototype是javascript的一个特性,不是那个有名的prototype框架: var string="hello world"; try{ alert(string.phone()); }catch(e){alert(e);} String.prototype.phone=function() { return "159-10957151"; } alert(string.phone()); [Ctrl+A 全选 注:如

  • 理解JavaScript变量作用域更轻松

    JavaScript本身作为一门简单的语言,就其变量作用域问题一样令不少人头晕,这主要是因为JavaScript闭包的存在.本文不打算深入讲解JavaScript变量作用域问题(其实本人也没有能力能把这一话题讲的深入些),也不讲"闭包"话题,本文只讨论最实用的JavaScript作用域知识点. 一.JavaScript作用域分类 JavaScript就两种作用域:全局(window).函数级(function).函数级(function)不要理解为"块级(大括号{}级)&qu

随机推荐