为什么我的JavaScript函数名称会发生​​冲突?

ank*_*981 97 javascript function

我写了下面的脚本,只是为了看一个变量和一个分配了函数的函数的名字发生冲突时会发生什么:

var f = function() {
    console.log("Me original.");
}

function f() {
    console.log("Me duplicate.");
}

f();
Run Code Online (Sandbox Code Playgroud)

我得到的输出是"我原创".为什么没有调用其他函数?

另外,如果我将原来的作业改为var f = new function() {,我会得到"我原创",然后是TypeError说object is not a function.有人可以解释一下吗?

Ben*_*aum 171

函数声明在JavaScript中被提升(移到顶部).虽然在解析顺序方面不正确,但由于函数声明被挂起,因此您所拥有的代码在语义上与以下相同:

function f() {
    console.log("Me duplicate.");
}
var f = function() {
    console.log("Me original.");
}


f();
Run Code Online (Sandbox Code Playgroud)

反过来,除了函数的名称外,它与以下内容相同:

var f = function() {
    console.log("Me duplicate.");
}
var f = function() {
    console.log("Me original.");
}


f();
Run Code Online (Sandbox Code Playgroud)

反过来,由于可变吊装与以下相同:

var f;
f = function() {
    console.log("Me duplicate.");
}
f = function() {
    console.log("Me original.");
}

f();
Run Code Online (Sandbox Code Playgroud)

哪个解释了你得到的东西,你正在重写这个功能.更一般地说,varJavaScript中允许多个声明 - var x = 3; var x = 5完全合法.在新的ECMAScript 6标准中,let声明禁止这样做.

@kangax的这篇文章在javascript中揭开功能的神秘面纱方面做得非常出色

  • @djechlin在这个问题的背景下 - 是的.通常,它更微妙 - 请参阅http://stackoverflow.com/questions/336859/var-functionname-function-vs-function-functionname.从编译器的角度来看,它们是不同的 - 但从程序员的角度来看 - 我们已经足够_Cose足以声称它.这就是为什么我添加那么长的"虽然在解析顺序方面不正确,但你所拥有的代码在语义上与"相同而不是说"与"相同".好点子. (6认同)
  • 在严格模式下,您不能在同一范围内两次`var`相同的名称. (5认同)
  • "这应该是显而易见的" - 也许是_you_,但是对我来说这一点并不明显,当他提出并命名时,以及更一般地说如何在JavaScript中管理词汇环境时,OP并不明显首次向我学习JavaScript时最难掌握的事情.我不会那么快地侮辱那些不理解它的人. (4认同)
  • 你能真正简化`函数f()`到`var f = function()`吗?提升和功能名称真的是*唯一*区别吗? (2认同)
  • @ bjb568:怎么回事? (2认同)

JLR*_*she 10

如果看起来没有人回答你的后续问题,那么我会在这里回答,尽管你通常应该将后续问题作为单独的问题来回答.

你问为什么这个:

var f = new function() {
    console.log("Me original.");
}

function f() {
    console.log("Me duplicate.");
}

f();
Run Code Online (Sandbox Code Playgroud)

打印出"我原创".然后是一个错误.

这里发生的是new导致函数用作构造函数.所以这相当于以下内容:

function myConstructor() {
    console.log("Me original.");
}
var f = new myConstructor();

function f() {
    console.log("Me duplicate.");
}

f();
Run Code Online (Sandbox Code Playgroud)

并且由于Benjamin解释的功能提升,上面基本上等同于:

var myConstructor = function() {
    console.log("Me original.");
};
var f = function() {
    console.log("Me duplicate.");
};

f = new myConstructor();

f();
Run Code Online (Sandbox Code Playgroud)

这个表达式:

var f = new function() {
    console.log("Me original.");
}
Run Code Online (Sandbox Code Playgroud)

f使用匿名函数作为构造函数,导致构造和分配新对象."我原创." 在构造函数执行时打印出来.但是构造的对象本身并不是一个函数,所以当它最终执行时:

f();
Run Code Online (Sandbox Code Playgroud)

你得到一个错误,因为f它不是一个函数.