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


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

    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

  • 相关阅读:
    JDK环境变量配置
    Leetcode 645. 错误的集合
    map、vector内存释放
    Leetcode 605. 种花问题(终于解决)
    QT自定义QTABLEWIDGET
    Qtcreator调试源码
    Eclipse安装教程
    C/C++常用工具库
    pandas目录
    Lesson3——Pandas Series结构
  • 原文地址:https://www.cnblogs.com/xianshenglu/p/8110622.html
Copyright © 2020-2023  润新知