JavaScript作用域体会

JavaScript作用域体会

先来看看MDN上对作用域的描述:

当前的执行上下文。值和表达式在其中 “可见” 或可被访问到的上下文。如果一个变量或者其他表达式不 “在当前的作用域中”,那么它就是不可用的。

从字面上看,“作用域”就是变量起作用的范围。那“作用域”的存在对我们写代码有什么作用呢?

程序的执行是要占用内存的,我们定义的变量是在内存中开辟空间来存放的,在程序执行完毕之前,如果不进行垃圾回收,那已经用不上的变量在内存中仍然会占据空间,如果程序特别大,那随着程序运行,它所占用的内存也会越来越大,这里暂时不讨论是否限定了程序的最大占用内存。

因此垃圾回收机制就非常有必要了,当一个变量在程序中某个地方之后再也用不到,那就应该被回收掉,那怎么确定变量“再也用不到了”?

当当当当,作用域的概念不就用上了。我们规定了作用域的概念,比如用一些特殊的标记(比如大括号{})来划定一个范围,如果一个变量是在该范围内声明的,它的作用域就是这个划定的范围。

当程序进入到该范围进行执行,所声明的变量就会被垃圾回收器标记为该作用域的变量,当程序执行完该范围内的代码,并跳出该范围去执行其他代码后,垃圾回收器就认为该范围中定义的变量已经“没有作用”了,进而将其回收处理。

这当然只是我的看法啦,如果有什么错误的地方请大胆指正。

下面就来看看一些有趣的东西。

我们猜猜看下面代码执行结果是什么样的:

var a = 100;
(function(){
	console.log(a);
	a = 5;
	console.log(window.a);
	var a = 200;
	console.log(a);
})();

结果是:undefined 、100 、 200
按照规范,var a = 10定义了一个全局变量 a ,那第一个console.log(a)应该打印100才对,但是却是未定义,这是为什么呢?

再来看下面代码:

var a = 100;
		(function(){
			console.log(a);
			a = 5;
			console.log(window.a);
			// var a = 200;
			console.log(a);
		})();

这里,我们把函数内对变量a 的声明注释掉,再来执行,输出结果是:
100 、 5 、 200

显然,这次我们又能访问到全局的变量a了。为啥?

俗气点说,应该是在程序开始执行前,会对代码进行一遍扫描,看看哪里定义了变量,然后会把声明隐式放到当前作用域的最前面,也就是说 var a = 20 被拆成了两部分,即 var a, a = 20, 其中 var a 会放到函数作用域的最前面,因此第一次的代码应该是这样子的:

var a = 100;
		(function(){
			var a
			console.log(a);
			a = 5;
			console.log(window.a);
			a = 200;
			console.log(a);
		})();

局部变量比全局变量优先级别高,当没有明确指出a是全局的还是局部的,优先认为是局部变量。
这样,第一次打印的时候没有对 a 赋值,因此打印出了undefined,第二次打印的时候虽然已经赋值为 a = 5 , 但是打印的是window对象的 a , 按照规范,显然是可以访问到的,因此是全局变量 a 被打印出来。而第三次打印的 a 是200,优先取了局部变量 a 进行操作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值