2016-03-02 47 views
0

以下代码片段显示一个基本对象,其中包含变量str,成员变量hello和成员函数test。我以为我知道JS很好,并期望此代码失败,因为test函数将被悬挂在顶部,并且将无法访问strvm变量。然后我惊讶地发现这实际上起作用。为什么这个代码的功能?起吊是否仍然发生?JS提升功能。 (为什么此代码段工作?)

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! 
+1

提升不影响范围... – elclanrs

+0

总是发生提升 –

+1

为什么它无法访问变量?它仍然在相同的范围内。 – Bergi

回答

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 
+0

只有变量声明被挂起。赋值'vm = this'不会移动到顶部。 (好的,由Bergi编辑修复) – Oriol

+0

@Bergi感谢您的快速解决。这在技术上是准确的,但我可以看到悬挂变量之前的函数如何仍然会令人困惑。从技术上讲,他们同时存在,因为第二次传球,但在技术上仍然准确的时候很难显示。 –

+2

我刚刚检查了规范,它更像'var fm,str,test; test = function(){...}'。随意将它移动到'var'声明的下面,正如你所说的那样无关紧要。 – Bergi

0

所有声明都提升到其封闭范围容器的顶部。

函数声明,如:

function foo(){ } 

将被吊起到其封闭的范围的顶部,因此它可以由被写入前的功能代码调用。

变量声明也被挂起。所以,这样的代码:

var x = 10; 

将体验提升为好。但前一个例子中只有宣布,所以只有

var x 

已被吊起。直到达到实际的代码位置才会发生x = 10分配。

类似地,函数表达式的工作方式也是一样的。有了这个代码:

var f = function() {}; 

只有var f悬挂,而不是分配。如果在实际代码位置到达之前尝试调用f,则会收到一个错误,指出f不是函数。

你的代码的工作,只是因为当你调用:

var s = new SomeObject(); 

,功能测试是不执行,但所有的变量赋值的。所以,当时间到了这个时候:

s.test(); 

所有的变量和函数都准备好了。

相关问题