前端面试题: 请解释什么是函数的作用域?

今天做到了一道题:请解释什么是函数的作用域?

我给的答案是:

函数的作用域是指函数执行到内部后创建的数据空间,在函数的作用域内,let定义的变量的有效期为函数作用域

AI觉得我答得比较简单:回答基本正确,但可以补充更多细节来提高回答质量。

正好就查一下,函数作用域在javascript里到底是什么。

经查实,前端考察作用域主要考察的是一种例外情况,就是在函数内的块里面定义的变量可能被抬升到函数级别的问题,例如下面的golang例子

var a = 1

func TestScope(t *testing.T) {
	//测试golang的作用域
	t.Log("a=", a)
	if true {
		var a = 2
		t.Log("a=", a)
	}
}

打印为:

test.go:29: a= 1

test.go:32: a= 2

第一次打印时,a应该是全局的第一行定义的a,所以打印1

第二次,在if这个独立的作用域里面定义了一个a,覆盖了全局的a,所以第二个打印,a=2

扫描二维码关注公众号,回复: 17041124 查看本文章

再来看对应的javascript版本

var var_a = 1
function test_Scope(){
	console.log(var_a)
	if (true){
		var var_a = 2
		console.log(var_a)
	}
	logc()
}
var var_a = 1
function test_Scope(){
	console.log(var_a)
	if (true){
		var var_a = 2
		console.log(var_a)
	}
}
test_Scope()

打印却是:

这里面第一次打印的时候,按其他语言应该还是全局的1才对,但是因为javascript把函数里面所有定义过的变量都放在了一个统一的函数作用域里面,使得这时,运行时认为var_a已经有了,只是还未赋值。

同样的问题在循环里也有

for (var i = 0; i < 10; i++) {    
    console.log(i);    
}    
console.log(i);  // 10 i只是for里面的函数,按道理在这里应该是undefined

而我回答的let确实是为了解决这个问题存在的:

来看上面的程序的let版本

let var_a = 1
function test_Scope(){
	console.log(var_a)
	if (true){
		let var_a = 2
		console.log(var_a)
	}
}
test_Scope()

打印则变成了

这就和其他语言的定义一致了。

所以如果再答我认为应该这样回答:

函数的作用域是指函数执行到内部后创建的数据空间,在函数的作用域内,var定义的变量具有相同的共同作用域,let定义的变量只有块状定义域,从定义语句开始,到所属的大括号结束,编写程序时应注意javascript和其他语言的不同,避免造成定义不一致的问题。

猜你喜欢

转载自blog.csdn.net/baijiafan/article/details/133036138