JS作用域与作用域链附测试题

分类

全局作用域
函数作用域
块级作用域(ES6之后)

作用

隔离变量,不同作用域下同名变量不会有冲突

作用域与执行上下文

  • 区别
    – 除全局作用域之外,每个函数都会创建自己的作用域,作用域在函数定义时就已经确定了(即静态作用域)。而不是在函数调用时(即动态作用域)
    – 全局执行上下文环境是在全局作用域确定之后,js代码执行之前创建
    – 函数执行上下文环境是在调用函数时,函数体代码执行之前创建
    – 作用域是静态的,只要函数定义好了就一直存在,且不会再变化
    – 上下文环境是动态的,调用函数时创建,函数调用结束时上下文环境就会被释放
  • 联系
    – 上下文环境是属于所在作用域的
    – 全局上下文环境属于全局作用域
    – 函数上下文环境属于对应的函数作用域

作用域与执行上下文环境的关系

在这里插入图片描述

作用域链

  • 理解
    – 多个上下级关系的作用域形成的链,它的方向是从下向上的(从内到外)
    – 查找变量时就是沿着作用域链来查找的
  • 查找一个变量的查找规则
    – 在当前作用域下的执行上下文中查找对应的属性,如果有直接返回,否则进入上一级作用域
    – 在上一级作用域的执行上下文中查找对应的属性,如果有直接返回,否则进入更上一级作用域
    – 再次执行2的相同操作,直到全局使用域,如果还找不到就抛出找不到的异常
var a = 1
function fn1() {
	var b = 2
	function fn2() {
		var c = 3
		console.log(c)	// 找到当前作用域里执行上下文对象中的变量c
		console.log(b)	// 当前作用域未找到,继续向上查找.....找到b
		console.log(a)	// 当前作用域未找到,在全局作用域中的执行上下文对象中找到a
		console.log(d)	// 一直未找到,将报出错误
	}
	fn2()
}

作用域示意图

全局作用域->fn作用域->bar作用域,形成了一个作用域链
在这里插入图片描述

测试题

var x = 10;
function fn() {
	console.log(x)
}
function show(f) {
	var x = 20
	f();
}
show(fn);

上面的代码将打印10
注意,函数是按作用域链的顺序查找使用的变量,而不是按执行上下文栈的顺序查找

var fn = function() {
	console.log(fn)
}
fn()

var obj = {
	fn2: function() {
		console.log(fn2)	// 改成this.fn2 或 obj.fn2 都可以正确执行
	}
}
obj.fn2()

第一个fn() 将输出fn函数本身的代码
第二个obj.fn2()会报错,原因是函数执行时是按作用域链依次查找使用到的变量的,当在函数fn2 内部找不到fn2时,将会在全局作用域中查找,而全局作用域中,没有直接保存fn2变量,而是存在obj对象中,所以找不到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tanleiDD

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值