JavaScript学习之旅-7(原创)

在上一篇文章中,我们主要学习在JavaScript中,如何定义函数(也称方法),使用函数,如何使用arguments去规避传参的风险。这一篇文章我们主要学习在JavaScript中变量的作用域与解构赋值。

概念一:在JavaScript中,用var申明的变量实际上是有作用域的。

我们首先来复习下在Java中成员变量和局部变量是如何定义和使用的。

成员变量:

在类里面定义的变量叫做成员变量;

如果在变量有static关键字修饰,就叫作静态变量或类变量;

如果该变量没有static关键字修饰,就叫作非静态变量或实例变量;

局部变量:

方法内定义的变量、形参、代码块中定义的变量都叫做局部变量;

另外,成员变量可以不显式初始化,它们可以由系统设定默认值;

但是局部变量没有默认值,在使用前必须赋值才可以使用。

还有,在内存中的位置也不一样。

成员变量在所在类被实例化后,存在堆内存中;局部变量在所在方法调用时,存在栈内存空间中。

复习完了Java,那么首先讨论变量的作用域的第一个话题,在JavaScript中,变量的全局作用域是什么?

首先,不在任何函数内定义的变量,就具有全局作用域。如下图


img_a65d29e878f66c6bd9b3ae4a751095c4.png
全局变量


实际上,JavaScript默认有一个全局对象window,全局作用域的变量实际上被绑定到window的一个属性,既然是绑定在window中,我们就可以直接使用,如下图


img_2b8a581aeca6cfcf1657e548ef32ad86.png
window全局使用变量

我们在学习函数的基础的时候说道每一个function有两种表达形式:一种是纯粹的function,还有一种是function就可以代表一个var变量,因此,每一个具体的函数如果用var变量来表示的话,这也是一个全局变量

img_193a55159d7238286efeb8a4cf37d157.png
直接使用方法

综上:使用window对象,也可以直接调用上面的test方法,实践检测:


img_6a25c2a54c54a4ff225d1196e57fa047.png
window对象调用

结论:根据上面的例子,我们可以判断JavaScript实际上有一个全局作用域。任何变量(函数也视为变量),如果没有在当前函数作用域中找到,就会继续往上查找,最后如果在全局作用域中也没有找到,则报ReferenceError错误(也就是类似我们java的空指针)。

老司机可能会说,上面说到了,全局变量会绑定到window上。如果不同的JavaScript文件如果使用了相同的全局变量,或者定义了相同名字的顶层函数,这种情况该怎么处理?

解决办法:减少命名冲突的一个有效方法是把 自己的所有变量和函数全部绑定到一个全局变量中。


img_e084fa160cc0a8dac8122ce930884aa2.png

我们可以把自己的代码放入到自己唯一INFO中(根据自己的需求去定义即可),这样会大大减少全局变量冲突的可能,而且会显著提高代码的阅读性和质量。

说完了JavaScript变量的全局作用域,那么局部作用域是什么?

由于JavaScript的变量作用域实际上是在函数内部,但是我们在for循环等语句中是无法定义具有局部作用域的变量的。为了解决块级作用域,ES6引入了新的关键字let,用let关键字替代var可以申明一个块级作用域的变量。

常量:

在JavaScript中,声明常量的方式有两种,第一种是在全局变量中使用,变量名全部大写,这一种是通过书写规范去表示这是一个常量,不要修改它的值;但是在 ES6 标准中,引入了新的关键字 const 去定义常量,这里就不演示了。(简单理解就是Java中的final关键字)

关于var申明的变量实际上是有作用域的必须记住的一些概念:

A:如果一个变量在函数(方法)体内部申明,则该变量的作用域为整个函数体,在函数外不可引用该变量。

img_cad74d05e3e30d408a89d66fd863e837.png
无法在函数体外引用变量a

B:如果两个不同的函数各自申明了同一个变量,那么该变量只在各自的函数体内起作用。(只能用在自己的方法内)


img_342b87ca4d65e8684efbabae136a78fc.png
不同函数申明同名变量不影响  

C:JavaScript的函数可以嵌套,此时,内部函数可以访问外部函数定义的变量,反过来则不行


img_fed972509570293afb36a5d2cc9b9812.png
内外部变量的限制规则

D:如果内部函数和外部函数的变量名重名怎么办?那么,内部函数的变量将“屏蔽”外部函数的变量。

拓展:变量提升


img_8535ff9c9552ddd32983b41de4cb7bbd.png
变量提升

JavaScript的方法定义有个特点,它首先会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部,第三行的 var x = 'Hello, ' + y ;  这一行并没有报错,原因是变量y在稍后申明了。但是console.log 显示 Hello, undefined,说明变量 y 的值为undefined。这正是因为JavaScript引擎自动提升了变量y的声明,但不会提升变量y的赋值。因此我们在方法内部定义变量时,请严格遵守“在方法内部首先申明所有变量,然后在使用”这一开发原则。

说完了JavaScript中变量的作用域,接下来我们在谈谈解构赋值。

解构赋值:

什么是解构赋值?

解构赋值 就是可以同时对一组变量进行赋值。从ES6开始,JavaScript引入了这一新特性,它大大提高了开发效率。它为什么会提高开发效率,我们先从数组说起。

首先,如何把一个数组的元素分别赋值给几个变量?有人说,简单,洋洋洒洒就是以下代码

img_8efee9bd49eab9d6a7b770b1e627d482.png
数组元素赋值变量

嗯,上面的方式的确做到了,轻松无痛苦。但是使用了新特性解构赋值的话,先看图

img_cfb40c176d4f3c9ed7e05bb671301f30.png
解构赋值 - 1 

使用了解构赋值就只有两行代码 即可完成上面的事情(x, y, z分别被赋值为数组对应元素)。

需要注意的有以下几点:

A:对数组元素进行解构赋值时,多个变量要用[ ... ]括起来

B:如果数组本身还有嵌套,也可以通过下面的形式进行解构赋值。(注意嵌套层次和位置要保持一致)


img_1574b607b1919d0431172470e4002a49.png
解构赋值 - 2   

C:解构赋值还可以忽略某些元素


img_cb78a36213bef7860eb2a36102c45813.png
解构赋值 - 3

注意,这里的  z 成功打印出了数值,但是 x y 都抛出了异常,所以我们还是需要严格遵循代码规范去编写代码

D:如果需要从一个对象中取出若干属性,也可以使用解构赋值,便于快速获取对象的指定属性:


img_7947c75ba051ac2f521ba7e70307d1c4.png
解构赋值 - 4

从图中我们清楚的可以看到,我们成功的将 person对象的 name、age、passport全部成功的打印出来了。

E:对一个对象进行解构赋值时,同样可以直接对嵌套的对象属性进行赋值,但需要保证对应层次一致即可。 如下图

img_f49b4bce606de29f1c3f40eceb0025cb.png
解构赋值 - 5

F:使用解构赋值对对象属性进行赋值时,如果对应的属性不存在,变量将被赋值为undefined。

G:解构赋值还可以使用默认值,这样就避免了不存在的属性返回undefined的问题,如下图

img_57207d042c5730fde6824272a7d7dfec.png
解构赋值 - 6

这里没有在person对象中声明single字段,但是我们可以直接在解构赋值里面使用默认值。

H:有些时候,如果变量已经被声明了,再次赋值的时候,正确的写法也会报语法错误,如下图


img_3e058a2e619b9d168fb1ed0ca32f0ed6.png
解构赋值 - 7

解决办法1:不单独声明 var变量 x,y,两行合并成一行

解决办法2:使用括号,如下图(推荐用法):

img_8d4429419d989a140f953825b3380b81.png
解构赋值的格式问题

目前支持解构赋值的浏览器包括Chrome,Firefox,Edge等。

本篇文章学习的是关于变量的作用域与解构赋值,篇幅较长内容也很多,需要自己耗时间多消化,变量的作用域与解构赋值的基本内容就结束了。

未完待续。。。

如果这篇文章对你有帮助,希望各位看官留下宝贵的star,谢谢。

Ps:著作权归作者所有,转载请注明作者, 商业转载请联系作者获得授权,非商业转载请注明出处(开头或结尾请添加转载出处,添加原文url地址),文章请勿滥用,也希望大家尊重笔者的劳动成果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值