我们进行编程当然少不了定义变量,其实每一个变量都是有他活动范围,也就是作用域,说白了就是在这个范围内我们可以访问到这个值。其实所谓作用域就是将我们应用(代码)划分为一个一个小块,每个变量都是相对于一个小块才有效。小块是可以嵌套,是有层级关系的。
在早期的 JavaScript 中变量作用域函数中,在块级别是没有作用域的概念的,这个是让从其他语言转移过来的开发人员和新手不解的地方。我们可以通过闭包的形式来实现在块级别作用域效果。
![8207483-e40d8188732c0fc3.jpg](https://upload-images.jianshu.io/upload_images/8207483-e40d8188732c0fc3.jpg)
local1 作用域就是函数 foo 中,所以我们可以打印变量。
![8207483-8fdc07261f294791.jpg](https://upload-images.jianshu.io/upload_images/8207483-8fdc07261f294791.jpg)
如何想要在作用域外访问该局部变量 lcoal1 就会抛出 undefined 异常。
![8207483-2625684508b63008.jpg](https://upload-images.jianshu.io/upload_images/8207483-2625684508b63008.jpg)
我们通过大括号定义块级别的代码,然后在块中定义一个局部变量 local2
![8207483-0c11c7ca2cf4ffc9.jpg](https://upload-images.jianshu.io/upload_images/8207483-0c11c7ca2cf4ffc9.jpg)
因为没有块级别作用域,我们是可以获取 local2 在 { } 以外的位置。
![8207483-7aaf7f927fe52ef5.jpg](https://upload-images.jianshu.io/upload_images/8207483-7aaf7f927fe52ef5.jpg)
但是es6 新的特性为我们提供块级别的变量 let ,通过 let 定义变量就具有块级别的作用域了。
![8207483-9121f4a7f1a78858.jpg](https://upload-images.jianshu.io/upload_images/8207483-9121f4a7f1a78858.jpg)
![8207483-81209dd33b08ebfa.jpg](https://upload-images.jianshu.io/upload_images/8207483-81209dd33b08ebfa.jpg)
![8207483-eb168c5e58afe514.jpg](https://upload-images.jianshu.io/upload_images/8207483-eb168c5e58afe514.jpg)
![8207483-c6f12a3dddc67aa7.jpg](https://upload-images.jianshu.io/upload_images/8207483-c6f12a3dddc67aa7.jpg)
定义一个变量 n = 4,然后我们随后可以修改这个变量通过重新赋值。
![8207483-3c8bf8d97749d5bd.jpg](https://upload-images.jianshu.io/upload_images/8207483-3c8bf8d97749d5bd.jpg)
但是如果用 const 来定义一个变量,如果想为其重新赋值就会抛出异常提示您无法为不可变的变量进行重新赋值。
![8207483-ab3f068ed0eac13a.jpg](https://upload-images.jianshu.io/upload_images/8207483-ab3f068ed0eac13a.jpg)
![8207483-6bc3e67f571e4527.jpg](https://upload-images.jianshu.io/upload_images/8207483-6bc3e67f571e4527.jpg)
再进一步解释我们定义系数变量 factor = 2 然后使用系数进行计算。
![8207483-8ffa56a9307333cf.jpg](https://upload-images.jianshu.io/upload_images/8207483-8ffa56a9307333cf.jpg)
![8207483-94a4ca84912cf37a.jpg](https://upload-images.jianshu.io/upload_images/8207483-94a4ca84912cf37a.jpg)
![8207483-4803e73bbf2a67e5.jpg](https://upload-images.jianshu.io/upload_images/8207483-4803e73bbf2a67e5.jpg)
但是如果随后我们不小心修改系数,我们计算结果就会受到影响,所以这种情况我们就应该使用 const 来定我们系数以确保他不会被修改。
![8207483-c97c772373423a3d.jpg](https://upload-images.jianshu.io/upload_images/8207483-c97c772373423a3d.jpg)
我们可以通过 const 来定义变量,接受一个对象作为变量值。
![8207483-ad2a2e860fdbc495.jpg](https://upload-images.jianshu.io/upload_images/8207483-ad2a2e860fdbc495.jpg)
然后我们尝试为 sam 重新赋值 sam = sam 同样会受到不可变变量无法修改的错误。
![8207483-a000e13f7affe745.jpg](https://upload-images.jianshu.io/upload_images/8207483-a000e13f7affe745.jpg)
但是 const 是无法确保这个对象属性不会被修改的,也就是无法确保对象的属性值是不可变的。
![8207483-dc762c602a998428.jpg](https://upload-images.jianshu.io/upload_images/8207483-dc762c602a998428.jpg)
虽然我们无法修改 sam 但是我们是可以随意修改 sam 的属性值的。
![8207483-4a90ad3c79778e88.jpg](https://upload-images.jianshu.io/upload_images/8207483-4a90ad3c79778e88.jpg)
那么我们应该如何做来确保这个这个对象属性值也是无法修改的呢?我们可以使用 Object.freeze 来冻结这个对象的属性值以避免被随意修改。
![8207483-1d09e061d05a1123.jpg](https://upload-images.jianshu.io/upload_images/8207483-1d09e061d05a1123.jpg)
![8207483-a5410f0772c9c046.jpg](https://upload-images.jianshu.io/upload_images/8207483-a5410f0772c9c046.jpg)
![8207483-5a5d48d78f420141.jpg](https://upload-images.jianshu.io/upload_images/8207483-5a5d48d78f420141.jpg)
![8207483-0316dbf2f3f05b6c.jpg](https://upload-images.jianshu.io/upload_images/8207483-0316dbf2f3f05b6c.jpg)
![8207483-9971c5d833cf8438.jpg](https://upload-images.jianshu.io/upload_images/8207483-9971c5d833cf8438.jpg)