简体   繁体   中英

JS hoisting functions. ( Why does this code snippet work? )

The following code snippet shows a basic object that contains a variable str , a member variable hello , and a member function test . I thought I knew JS pretty well and expected this code to fail because the test function would be hoisted to the top and would be unable to access the str or vm variable. I was then surprised to see that this actually works. Why does this code function? Does hoisting still occur?

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

Output:

hello
testig!

Due to hoisting, you essentially end up with this:

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

All declarations are hoisted to the top of their enclosing scope container.

A function declaration, such as:

 function foo(){ }

Will be hoisted to the top of its enclosing scope, so it may be called by code that is written BEFORE the function is.

Variable declarations are hoisted as well. So, code such as:

 var x = 10;

Will experience hoisting as well. BUT, only declarations are hoisted, so in the previous example, only

 var x

is hoisted. The x = 10 assignment won't happen until the actual code location is reached.

Similarly, function expressions work the same way. With this code:

 var f = function() {};

Only the var f is hoisted, not the assignment. If you were to try to call f before the actual code location were reached, you would receive an error indicating that f is not a function.

Your code works simply because when you call:

 var s = new SomeObject();

The function test is not executed, but all the variable assignments are. So, when the time comes for this:

 s.test();

All the variables and the function are ready to go.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM