前言
你有你的家,我有我的家,该划分好划分好。就像我们生活中,每个人家里都有各自的房间,大家知道哪些地方是自己的,这样就不会乱闯乱动别人的私人物品。编程的时候也有类似的规则,叫做 “作用域”。它就像给电脑里的代码分配房间或者说是领土,让它们知道哪里是自己的活动区域,哪里是自己不能去的地方。就好比,台湾永远是中国的一样,其他国家不要多bb。这样一来,不同的代码块知道自己该用哪些变量(就像家里的东西),不会混淆,这样程序运行起来就更有序、更顺利了。
编译三部曲
- 词法分析:也就是分词。这就好像是一位细致的图书管理员,将一堆书本(源代码)分类成一个个可管理的书架。它分辨出字符串、数字、关键字等。比如说:
var a =123,编译器就会识别四个东西 : var ,a, =,123(分词)。 - 解析:在书本被分类后,就要开始解析了,这好比将单词组成句子,理解其的含义。解析每个东西的作用 ,弄清楚是干嘛的(解析)。
- 生成代码:最后,转换为机器可理解的语言。生成代码
var a = 123
代码的领土划分
-
全局作用域:相当于一个广阔无垠的公共空间,所有变量在此皆可见,就好像地球一样,所有国家都在这里。
-
函数作用域:比做成一个国家吧,函数内的变量只在自己国家的范围内生效,保护了数据的隐私,避免了不必要的干扰,总不能让其他国家窥探我国机密吧。
例如:
var a=1
function foo() {
var a=2
console.log(a)
}
foo();
全局作用域中就包括以下:
var a=1
function foo() {}
foo();
函数作用域就包括以下:
var a=2
console.log(a)
- 块级作用域:ES6新增的领域,由
{}围起的小天地,let和const守护着其中的秘密,它们共同守护着局部数据的纯净,确保变量的生命期仅限于所属的代码块内。不让他人伸脚,自己也不伸手,就好像是闭关锁国一样。
例如:
let c = 5
{
let c = 2
console.log(c)
}
console.log(c)
第一个输出c的值就是2,第二个输出c的值就是5,因为在块级作用域,{}内的只能访问{}内的,{}外的只能访问{}外的
作用域法则:内外有别
内部作用域可以访问外部的作用域,反之则不行
如同国界,内部作用域可以自由探索地球的风景,而外界却无法窥视内部的奥秘。
例如:
var a=1
function foo() {
console.log(a)
}
foo();
这个输出的是1
function foo() {
var a=2
}
foo();
console.log(a)
而这个只能报错!!
词法作用域
简单来说,就是在写代码的时候就能确定的变量作用范围。想象一下,当你写程序时,每个变量就像是被分配了一个固定的“家”,这个“家”就是它的作用域。不论程序运行到哪里,变量都会记住它出生时所在的“家”。
更技术一点讲,词法作用域是在代码编写阶段,由代码的结构静态决定的。也就是说,变量在哪里定义,它就在哪里以及它内部的区域可用,而不会受到运行时调用位置的影响。比如,如果一个变量在函数体内定义,那么这个变量就只在这个函数体内部可见,出了这个函数体,变量就好像不存在一样。
欺骗词法作用域
- eval():让原本不属于这里的代码,变得好像天生就定义在了这里一样,例如:
function foo(a,str) {
eval(str);
console.log(a,b);
}
foo(1,'var b=2') ;
注意:这里调用foo函数的时候传入函数的var b =2是字符串
那么如果没有eval(),输出的肯定是1,'var b=2',但是当eval() 出现,那么输出的就是1,2,神奇吧
- with():一旦修改对象中不存在的属性时,这个属性会泄露到全局,变成全局变量,例如:
var obj ={
a:1,
b:2 ,
c:3
}
with(obj) {
a=3
b=4
c=5
d=6
}
console.log(obj)
console.log(d)
console.log(obj)输出的值中没有d,所以d会跑到全局作用域去,变成全局变量,在全局中输出d的话就能输出结果6。怎么打个比方呢,就好像你去拿快递,你有四个快递,但是你拿到了五个,那你肯定只能拆开四个啊,另一个得还到快递站吧
var 与 let 的对决
- var:声明的变量存在声明提升,在全局声明的变量会被添加到
window对象上 - let:而它拒绝提升,严格遵循块级作用域的规则,更为安全可靠。
var a = 1
{
console.log(c)
var c = 2
}
这个输出undefined
let c = 1
{
console.log(c)//暂时性死区
let c = 2
}
这样就会报错,访问不到外面的c
总结
分好场地,划好线,不是自己的东西就别硬要去调用,不然会给你狠狠地报错哦!!!
是自己的永远是自己的,就好像台湾永远是中国不可分割的一部分一样。
写得不好的地方以及需要修改的地方,欢迎大佬亲临指正昂💞