JavaScript 中标准函数的作用域是什么?

What is the scope of a standard function in JavaScript?

我知道在 JavaScript 中有多种声明函数的方法。具体来说,我的疑问是声明函数的“标准”方式,假设我们有下一个函数:

function salute(name) {
    let phrase = `Hello ${name}, nice to meet you`;
    document.write(phrase + `<br/>`);
}

(我知道 document.write() 不是一个好习惯,但我只是用它来测试代码)。

现在,可以将另一个功能分配给 salute,例如:

salute = function(){
    document.write(`This is a different function <br/>`);
}

原始 salute 函数是否像 var variable/object 一样声明?我知道如果声明为 var,可以在同一范围内重新声明一个变量,例如:

var aVariable = 10;
var aVariable = 11;

但这不适用于 let 和 const,如下所述: Difference between var and let

继续原始代码,我意识到我可以使用 var:

重新声明 salute
var salute = function(){
    document.write(`This is a different function <br/>`);
}

但我不能对 let 或 const 做同样的事情。这让我得出结论,声明函数的“标准”方式具有隐式 var 作用域。我说得对吗?

在JavaScript中,对象和函数也是变量。因此可以根据此网站自动将功能视为全局:https://www.w3schools.com/js/js_scope.asp

这在很大程度上取决于您认为“标准”是什么,我会说答案是肯定的还是否定的。

在脚本的顶层环境中,您的函数的行为类似于变量声明(例如 var)。这意味着您甚至可以将相同的函数声明写两次,并且不会抛出任何错误。最后一个声明将覆盖前一个声明。

function test(){
    console.log(1);
}

function test(){
    console.log(2);
}
test(); //2

在函数定义中,行为几乎相同:

(function nested(){
    function test(){
        console.log(1);
    }

    function test(){
        console.log(2);
    }
    test(); //2
})()

注意这甚至可以是 strict 代码:

(function nested(){
    'use strict';
    function test(){
        console.log(1);
    }

    function test(){
        console.log(2);
    }
    test(); //2
})()

然而,一旦我们开始使用块和 strict 代码……事情开始发生变化……

'use strict';
{
    test();
    function test(){
        console.log(1);
    }

    function test(){
        console.log(2);
    } //SyntaxError
}

此外,与脚本顶级环境不同,模块在 strict 模式下的行为也像块(就函数声明而言)。

function test(){
    console.log(1);
}

function test(){
    console.log(2);
}
test(); //SyntaxError

它仍然不完全像 let 因为函数仍然被提升(let 变量在到达声明之前不会被初始化)而且它绝对不是不可变的 const 变量,因为您仍然可以覆盖函数。

'use strict';
{
    test = function(){
        console.log(2);
    }
    test(); //2
    function test(){
        console.log(1);
    }
}