今天做到了一道题:请解释什么是函数的作用域?
我给的答案是:
函数的作用域是指函数执行到内部后创建的数据空间,在函数的作用域内,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
再来看对应的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和其他语言的不同,避免造成定义不一致的问题。