以下代码段显示了一个基本对象,其中包含变量str
,成员变量hello
和成员函数test
。我以为我非常了解JS,并且期望此代码失败,因为test
函数将被提升到顶部,并且无法访问str
或vm
变量。然后我惊讶地发现这确实有效。为什么这段代码有效?吊装是否还会发生?
function SomeObject( ) {
var vm = this;
vm.hello = "hello";
vm.test = test;
var str = "testig!";
function test() {
console.log( vm.hello );
console.log( str );
}
}
var s = new SomeObject();
s.test();
输出:
hello
testig!
答案 0 :(得分:2)
由于吊装,你基本上就是这样:
function SomeObject() {
var vm;
var str;
var test;
test = function test() {
console.log(vm.hello);
console.log(str); // Works because we haven't run the function yet
}
vm = this;
vm.hello = 'hello';
vm.test = test;
str = 'testig'; // str now has a value, function hasn't been called yet
}
var s = new SomeObject();
s.test(); // Function is called after str has been given a value
答案 1 :(得分:0)
所有声明都悬挂在其封闭范围容器的顶部。
函数声明,例如:
function foo(){ }
将被提升到其封闭范围的顶部,因此可以通过在函数之前写入的代码调用它。
也会提升变量声明。所以,代码如:
var x = 10;
也会经历吊装。但是,只有声明被提升,所以在前面的例子中,只有
var x
被悬挂。在达到实际代码位置之前,x = 10
分配不会发生。
类似地,函数表达式的工作方式相同。使用此代码:
var f = function() {};
仅提升var f
,而不是作业。如果您在达到实际代码位置之前尝试调用f,则会收到错误,指示f不是函数。
您的代码之所以有效,只是因为您致电:
var s = new SomeObject();
不执行功能测试,但所有变量赋值都是。所以,到时候了:
s.test();
所有变量和功能都准备好了。