function test(){
var arr = [];
for(var i = 0; i < 5; i++){
arr[i] = function a() {
return i;
}
a();
}
return arr;
}
test();//a is not defined
function c(){
function d(){
console.log('2');
}
d();
}
c(); //2
为什么第一个是undefined呢,不是明明定义了a吗在之前?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
函数表达式的函数名字只属于它自己的作用域
以你第二段代码为样本改成函数表达式:
上面这样是没有问题的,但是改成这样:
引用错误
ReferenceError。作用域中查找标识符但是最后没有找到的时候就会抛出这个错误。
也就是说当前作用域中压根就没有以
d作为标识符的变量(函数)。(顺带一提,如果在这里找到了
d标识符,但是它不是函数无法运行,会抛出TypeError类型错误。)那么,标识符
d到底在哪个作用域?答案是它自己:
这里最后会把函数
d打印出来,在函数d内部是可以使用d标识符的。这里你想错了,它并没有定义一个名叫a的对象,这里的函数定义式是字面量定义,并非函数声明,这个
arr[i]=function a(){中的a可以省略,表示的是arr[i]这个函数的name,也就是arr[i].name是字符串"a".这个function前面没有东西的才是函数声明式写法,它会定义一个函数对象a。
function前面有东西的时候是字面量写法,此时a只是一个名字,不定义变量。
我们平时声明函数就是这样:
那如果这样呢:
再来看看:
所以,带名字的匿名函数,名字只能在内部作用域使用,不能在外部调用,充当arguments.callee的角色,并且只读。不能在内部调用,否则会栈溢出。
如果要实现你的代码:
实际上,你那个a定义了和没定义没什么区别的,请参照我的做法:
function a(){};
这是一个函数声明,相当于var a = function(){};
arr[i] = function a(){};
(function a(){})这是一个函数表达式,赋值的是arr[i],执行到这里才解析。
这里你是在给arr[i]赋值,它的值是一个函数,函数的名字是a,而不是声明和定义函数a的意思,如果在arr[i]后面console.log(arr[i]),你会发现有五个a函数。
只是一个变量定义并初始化语句,可以理解为系统创建一个函数对象theFunc,将其值赋给func后立即销毁。这种效果与赋值未命名函数这种直接量是一样的,只是有一个临时对象名。