gostone
gostone

Reputation: 11

Javascript: Run a function defined outside this closure as if it were defined inside this closure

I want to have a function A that accepts another function B as an argument, and then runs B as it were defined within the closure scope of A, i.e. has access to all the local variables.

For example, simplistically:

var A = function(B){
  var localC = "hi";
  B();
}

var B = function(){
  console.log(localC);
}

A(B); // to log 'hi'

The only way I have found is to use eval. Does ec6 give any better options maybe?

Upvotes: 0

Views: 108

Answers (3)

Halcyon
Halcyon

Reputation: 57693

You can make the context explicit and pass it to B:

var A = function(B){
    var context = {
        localC: "hi"
    };
    B(context);
}

var B = function(context){
    console.log(context.localC);
}

A(B); // hi

You can also use this with new and prototype:

var A = function() {
    this.localC = "hi";
}
A.prototype.b = function(context){
    console.log(this.localC);
}

var a = new A();
a.b(); // hi

or without the prototype:

var A = function() {
    this.localC = "hi";
}

var a = new A();
a.b = function(context){
    console.log(this.localC);
};
a.b(); // hi

You can use this with bind:

var a = {
    localC: "hi"
};
function B(foo) {
    console.log(this.localC, foo);
}
B.bind(a)("foo"); // hi foo
// .call:
B.call(a, "foo"); // hi foo

bind sets the context for this. call takes the context as it's first argument.


This one is not good:

var A = function(B){
    var localC = "hi";
    B.bind(this)(); // this is the global object, you need `new` to create a new scope
}

var B = function(){
    console.log(this.localC);
}
A(B); // undefined

Upvotes: 0

Alex Char
Alex Char

Reputation: 33218

One solution is to pass localC as argument in function B:

var A = function(B) {
  var localC = "hi";
  B(localC);
}

var B = function(localC) {
  console.log(localC);
}

A(B); // outputs hi

Alternative using arguments:

var A = function(B) {
   var localC = "hi";
   B(localC, "test");
 }

 var B = function() {
   var i = 0;
   for (i; i < arguments.length; i++) {
     console.log(arguments[i]);
   }
 }

 A(B); // outputs hi, test

Upvotes: 1

Arunabh Trivedi
Arunabh Trivedi

Reputation: 91

var A = function(B){
  var self = this;
  self.localC = "hi";
  self.localD = "hello";
  B();
};

var B = function(){
  var self=this;
  alert(self.localD);
}

A(B); // to log 'hi'

Upvotes: 0

Related Questions