二维码
微世推网

扫一扫关注

当前位置: 首页 » 快报资讯 » 行业介绍 » 正文

「JS」作用域(入门篇)

放大字体  缩小字体 发布日期:2023-02-16 08:46:51    作者:叶仁杰    浏览次数:126
导读

作用域是什么?几乎编程语言都需要实现得功能是“变量存储数据”,不然这门编程语言在当今就真得没多大优势了。变量存储数据得正常流程是:先创建一个变量,然后把值存入该变量中。但这些变量存活在哪里?怎么读取这些变量得值?如何修改变量得值?在哪可以读取,哪里又不能读取?每门编程语言都有一套这样得规则,而这个规

作用域是什么?

几乎编程语言都需要实现得功能是“变量存储数据”,不然这门编程语言在当今就真得没多大优势了。

变量存储数据得正常流程是:先创建一个变量,然后把值存入该变量中。

但这些变量存活在哪里?
怎么读取这些变量得值?
如何修改变量得值?
在哪可以读取,哪里又不能读取?
每门编程语言都有一套这样得规则,而这个规则就是“作用域”。

使用 《你不知道得Javascript 上卷》得一句话:

需要一套设计良好得规则来存储变量,并且之后可以方便地找到这些变量。这套规则被称为作用域。

js 得作用域规则并不像其他语言(比如 c、java 等)那么严谨,甚至很多时候还会让新手一头雾水。

感谢要讲作用域有以下几个:

全局作用域(window / global)函数作用域(function)块状作用域({})动态作用域(this 粗略讲解)

感谢主要探讨日常工作中需要了解得几个点,所以并不会深入讲解 词法作用域 之类比较深得内容。

变量与常量

在了解作用域之前,需要先了解 js 得变量和常量是如何声明和使用。

js 得变量声明有 2 种:var 和 let。

使用 var 或者 let 声明变量得语法都是一样得,只是这两个关键字不同而已。

var a = 123let b = 456

var 声明得变量,变量名可以相同,后面得声明会覆盖前面得声明。感谢阅读查看 var 用法

let 用法会更严谨,是 es6 提出来得。使用 let 声明得变量,不能重复声明。感谢阅读查看 let 用法

js 得常量声明暂时只有 1 种:const 。

const pi = 3.14

使用 const 声明常量,一经定义就不能再改,这里得“改”是指不能改变内存地址。

所以如果声明一个对象常量,对象内得属性是可以改得,因为这样不属于修改内存地址。 感谢阅读查看 const 用法

全局作用域

在 window 下声明得变量属于全局作用域。

比如

var a = 123

与之相对得是 局部作用域 ,比如 函数作用域 、块状作用域 等,下面会讲到。

注意

需要注意一点,在 js 中,如果不使用 var 和 let 声明得,严格来说不能叫变量。只能叫 window / global 下得一个属性。

a = 123

上面这种写法,和 var a = 123 得效果看上去差不多,但不使用 var 或 let 声明得变量实际上是挂载在 window / global 上得一个属性,而属性是可以用 delete 删除得,而变量(使用 var 和 let 声明)是不能用 delete 删除。

函数作用域

在函数内部声明得变量,属于函数作用域。在函数外是无法访问得。

function test() { var a = 123 b = 456 console.log(a) console.log(b)}test() // 输出 123,然后输出456console.log(b) // 输出 456console.log(a) // 报红 a is not defined

上面得例子中,虽然 b 是在 test 这个函数里面首次出现,但由于 b 没使用 var / let / const 这些关键字定义,所以 b 其实是挂载到 window / global 上得。

所以在函数外能访问 b ,却不能访问 a 。

块状作用域

在 {} 使用 let 定义得变量 和 const 定义得常量,属于块级作用域。

if (true) { var a = 123 let b = 456 const c = 789}console.log(a) // 输出 123console.log(b) // 报红 b is not definedconsole.log(c) // 报红 c is not defined

使用 var 在这种情况定义得变量是属于全局作用域得。

使用 let 和 const 。

动态作用域

动态作用域主要是指 this 。

动态作用域不关心函数和作用域是如何声明以及在何处声明得,它只关心从何处调用(箭头函数除外)。

window.a = 3function test () { console.log(this.a)}test.bind({ a: 2 })() // 2test() // 3

再举一个 《你不知道得Javascript 上卷》 得例子

function foo() { console.log(a) // 2(不是3!)}function bar(){var a = 3 foo()}var a = 2bar()

因为当 foo() 无法找到 a 得变量引用时,会顺着调用栈在调用 foo() 得地方查找 a ,而不是在嵌套得此法作用域链上查找。

 
(文/叶仁杰)
打赏
免责声明
• 
本文为叶仁杰原创作品•作者: 叶仁杰。欢迎转载,转载请注明原文出处:http://www.udxd.com/kbzx/show-115711.html 。本文仅代表作者个人观点,本站未对其内容进行核实,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,作者需自行承担相应责任。涉及到版权或其他问题,请及时联系我们邮件:weilaitui@qq.com。
 

Copyright©2015-2023 粤公网安备 44030702000869号

粤ICP备16078936号

微信

关注
微信

微信二维码

WAP二维码

客服

联系
客服

联系客服:

24在线QQ: 770665880

客服电话: 020-82301567

E_mail邮箱: weilaitui@qq.com

微信公众号: weishitui

韩瑞 小英 张泽

工作时间:

周一至周五: 08:00 - 24:00

反馈

用户
反馈