简体   繁体   中英

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, ie 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?

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 

 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' 

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

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