如果我在<head>
标记中执行此操作:
<script type="text/javascript" src="foo.js"></script>
在foo.js里面我这样做:
var foo = new Foo();
function Foo()
{
//code here
}
此代码是否可靠地实例化变量foo
,即使它包含在函数定义之上,或者我应该将其移动到文件的底部,如下所示:
function Foo()
{
//code here
}
var foo = new Foo();
答案 0 :(得分:5)
您的示例将适用于遵循ECMAScript标准的任何浏览器(至少都与此问题有关。)
参见specification的第10.3-10.5节。
首先设置局部范围,然后实际运行函数体。
阅读10.5(该部分真的不长),了解为什么@meder的答案是正确的。
10.5告诉以该顺序声明变量(如果某个名称出现两次则覆盖):
继承外部范围=设置将影响外部范围:
本地范围=设置不会影响外部范围:
undefined
)总而言之:
返回函数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
}
还返回内部函数x:
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;
}
答案 1 :(得分:4)
如果您通过var
定义它,则只需将其移至上方,例如:
var Foo = function(){};
var foo = new Foo;
否则,据我所知,解释器会提前读取函数定义。
答案 2 :(得分:3)
据我所知,由于吊装,JS会对您的代码执行此操作:
var foo; //var declarations hoisted up
function Foo(){ //function declarations hoisted up
//code here
}
foo = new Foo(); //the operation
所以它应该没问题。但是,我不仅仅依赖于吊装,因为至少对我来说,当声明到处都很难调试时。为了便于阅读,请以这种方式订购代码:
console.log(foo); //undefined
var foo = new Foo();
console.log(foo); //Foo
function Foo(){
//code here
}
console.log(foo); //Foo
//acts like:
var foo; //var declaration hoisted up
function Foo(){} //function declaration hoisted up
console.log(foo); //undefined
foo = new Foo();
console.log(foo); //Foo
console.log(foo); //Foo
console.log(foo); //undefined
function Foo(){
//code here
}
console.log(foo); //undefined
var foo = new Foo();
console.log(foo); //Foo
//acts like:
var foo; //var declaration hoisted up
function Foo(){} //function declaration hoisted up
console.log(foo); //undefined
console.log(foo); //undefined
foo = new Foo();
console.log(foo); //Foo