函数表达式中,函数名称在函数体内是只读的

我们来看一个函数定义表达式:

var f=function a(){
    console.log(arguments.callee.name);//返回当前执行函数的 name
};
f();// a

可能有人觉得奇怪哈,很正常,因为一般我们不这么写,要么不带 a ,要么就直接用函数声明语句了,不过这种写法有它的优势,用来递归的时候很方便,详情 戳这里

这里主要来分析 a 的作用域的,上面的例子就为证明一点:

赋值给 f 的函数名称是 a ,不是 f

关键是,这个 a 的作用域问题,我们在 f 执行完后,访问 a:

image

报错了,证明 a 不是全局变量,实际上书上也是这么说的:

image

测试下,逻辑上没有问题:

image

不过我们不仅于此,我们在函数内给 a 重新赋值:

var f = function a() {
    a = 3;
    console.log(a);
};
f();

返回的是函数本身,说明赋值失败了:

image

严格模式下,报错,字面理解就是赋值给了常量(注意 , ES6 新增了常量 const,对于常量是不能重复赋值的):

image

这说明:

函数定义表达式中带函数名称的,函数名称只能作为常量在函数体内访问,不可以被重新赋值的,非严格模式下静默失败,严格模式下报错;

既然知道了这个,如果在函数体内依然要给 a 赋值也不是不行,换成变量就可以了;

var f = function a() {
    var a = 3;
    console.log(a);
};
f();//返回 3

当然这样就不能继续用 a 来访问原来的函数了,虽然还有其他办法,但是这样修改明显是不合适的,可读性不好;

另外,在函数声明语句中是可以的修改函数名称,比如:

function a() {
    a = 3;
    console.log(a);
}
a();//3,a 变成 3

但是,放在 IIFE 中,又不行了;

(function a() {
    a = 3;
    console.log(a);//函数,修改失败;
})()
a;//error not defined;

当然,var 仍然是可行的,

(function a() {
    var a = 3;
    console.log(a);//3 成功
})()

对于 IIFE 中执行失败的解释,我猜测:

() 强制 js 引擎 把里面的函数声明语句当成了表达式,那么这种情况下,这个效果不就等价于 带名称的函数定义表达式么?这个时候,函数名称应该也是局部变量且只能在函数内部访问,不可修改;

文档上是这么说的:

参考资料:

JavaScript权威指南-第6版

文档

https://stackoverflow.com/questions/24021489/variable-in-function-body-and-function-itself-have-the-same-name-javascript/24022076#24022076

https://stackoverflow.com/questions/15129504/why-are-anonymous-function-expressions-and-named-function-expressions-initialize

转载于:https://www.cnblogs.com/xianshenglu/p/8110622.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值