Javascript 在函数声明之前调用它,与浏览器无关吗?

Javascript 在函数声明之前调用它,与浏览器无关吗?,javascript,Javascript,如果我在标记中执行此操作: <script type="text/javascript" src="foo.js"></script> 此代码是否可靠地实例化变量foo,即使它包含在函数定义上方,还是应该将其移到文件底部,如下所示: function Foo() { //code here } var foo = new Foo(); 据我所知,JS对您的代码做了以下处理: var foo; //var declarations hoisted

如果我在
标记中执行此操作:

<script type="text/javascript" src="foo.js"></script>
此代码是否可靠地实例化变量
foo
,即使它包含在函数定义上方,还是应该将其移到文件底部,如下所示:

function Foo()
{
   //code here
}
var foo = new Foo();

据我所知,JS对您的代码做了以下处理:

var foo;          //var declarations hoisted up
function Foo(){   //function declarations hoisted up
   //code here
}
foo = new Foo();  //the operation
所以应该没问题。然而,我不会完全依赖于提升,因为,至少对我来说,当声明到处都是的时候,很难调试。为了便于阅读,请按以下方式排列代码:

  • 变量声明
  • 功能
  • 操作


只有通过
var
定义它时,才需要将其移到上面,例如:

var Foo = function(){};
var foo = new Foo;

否则,据我所知,解释器会提前读取函数定义。

您的示例将在遵循ECMAScript标准的任何浏览器中工作(至少在这个问题上都可以)

见本手册第10.3-10.5节

首先设置本地范围,然后实际运行函数体

阅读10.5(这一节其实并不长)来理解为什么@meder的答案是正确的

如果您不想自己阅读规范: 10.5告知按照该顺序声明变量(如果某个名称出现两次,则覆盖):

继承自外部范围=设置将影响外部范围:

  • 周围范围的变量
  • 自己的函数名
本地范围=设置不会影响外部范围:

  • 参数(从左到右)
  • 参数对象
  • 声明所有内部变量(如果有,则不覆盖当前值,
    未定义,如果没有,则不覆盖当前值)
总而言之:

返回函数x本身:

function x() {
    return x;
}
返回参数x:

function x(x) {
    return x;
}
返回内部函数x:

function x(x) {
    return x; // the return does no harm, x is already set
    function x() {} // before the actual body is evaluated
}
function x(x) {
    var x; // in this case a no-op 
    return x;
    function x() {}
}
还返回内部函数x:

function x(x) {
    return x; // the return does no harm, x is already set
    function x() {} // before the actual body is evaluated
}
function x(x) {
    var x; // in this case a no-op 
    return x;
    function x() {}
}
返回42:

function x(x) {
    var x = 42; // overwrite x in local scope
    return x;
    function x() {}
}
返回第二个参数:

function x(x,x) { // assign left to right, last one "wins"
    return x; // arguments[0] would still name the first argument
}
当第二次调用
x
时返回2,因为x被设置为内部函数:

function x() {
    x = function() { return 2; } // set x in outer scope
    return 1;
}

我想他是在询问第一个示例中的
Foo
函数声明,而不是
Foo
变量声明,因为在该示例中,函数在其声明出现之前被调用。@amnotiam是的,变量可以命名为任何名称,我想知道如果把它放在Foo()函数的定义之上,它是否会被可靠地实例化。它还会提升function语句,并将其转换为
var Foo=function Foo(){/…}
@ClickUpvote:通过实例化,您会询问
新的Foo()
是否会工作,因为它与
函数Foo(){…}
的声明“不符合顺序”,对吗。。。无论如何,答案是肯定的。函数声明发生在封闭范围内的任何代码执行之前。我认为@Peter使用变量赋值语法来说明函数将可用,就像代码位于函数顶部一样。他用这种语法来解释它有点让人困惑。+1表示不使用“提升”,但请注意,相关部分正在进入,而不是函数上下文,这主要影响
的值。我不明白该规范如何回答我的问题?你能用英语翻译吗?简单来说,对于全局代码,
这个
被设置为全局对象,然后处理函数声明,然后是变量声明,然后是可执行语句。当输入每个函数时,都会发生类似的过程,但设置
的值和范围更为复杂。@RobG是的,我故意忽略了
。)您可能会发现本文很有帮助:
function x() {
    x = function() { return 2; } // set x in outer scope
    return 1;
}