JS吊装功能。 (为什么这段代码片段有效?)

时间:2016-03-02 23:40:49

标签: javascript

以下代码段显示了一个基本对象,其中包含变量str,成员变量hello和成员函数test。我以为我非常了解JS,并且期望此代码失败,因为test函数将被提升到顶部,并且无法访问strvm变量。然后我惊讶地发现这确实有效。为什么这段代码有效?吊装是否还会发生?

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!

2 个答案:

答案 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();

所有变量和功能都准备好了。