user7951676 user7951676 - 1 year ago 64
Javascript Question

Bring a new function into a closure

I've read a lot about closures and I use them regularly however I've found a case I don't understand.
Why isn't the hello variable accessible to my function I'm passing to test? Shouldn't it find it as it looks through the scope change?
My code:

(function($){
var hello="hello world"
$.test=function(a){
alert(hello+" 1")
a()}
})(this)
test(function(){alert(hello+" 2")})

Answer Source

JavaScript uses lexical scope (hat tip to deceze). Scope is determined by where a function is defined not by where it is passed or where it is called from.

If you want a function to have access to data in a variable from the scope it is passed to, you need to define it so it takes an argument, and then you need to pass the data.

"use strict";
(function($) {
  var hello = "hello world"
  $.test = function(a) {
    alert(hello + " 1")
    a(hello);
  }
})(this);
test(function(passed_data) {
  alert(passed_data + " 2")
});

This is a common design pattern. See the Promise API for instance:

myFirstPromise.then((successMessage) => {
  // successMessage is whatever we passed in the resolve(...) function above.
  // It doesn't have to be a string, but if it is only a succeed message, it probably will be.
  console.log("Yay! " + successMessage);
});

Note how the function passed to then() takes an argument which provides the data it is going to work on.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download