最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Calling a parent function inside a closure - Stack Overflow

programmeradmin1浏览0评论

I am having a really, really hard time trying call an object function inside of an asynchronous soap request. It basically boils down to this:

function Thing(request, response) {

    this.foo = function() {
        console.log("this is foo");
    }

    this.doThing = function() {
        // Get SOAP args
        args = { foo: this.request.cookies.foo };
        // From the SOAP npm package library
        soap.createClient(function(err, client) {
            client.doSomething(args, function(err, result) {
                // Somehow call foo(); <--- CAN'T FIND A WAY TO DO THIS
            });
        });
    }
}
// Make it so I can access this.request and this.response somehow
Thing.prototype = Object.create(AbstractThing); 

I have tried many things, but I believe it fundamentally es down to the fact that I cannot call this.foo() inside any of the asychrenous soap functions. Although I can pass a callback function into createClient, like so:

function Thing(request, response) {

    this.foo = function() {
        console.log("this is foo");
    }

    this.sendSoap = function(err, client) {
        // Get SOAP args
        args = { 
            foo: this.request.cookies.foo <--- this.cookies undefined
        }; 
        client.doSomething(args, function(err, result) {
            // Somehow call foo(); <--- CAN'T FIND A WAY TO DO THIS
        });
    }

    this.doThing = function() {
        // From the SOAP npm package library
        soap.createClient(this.sendSoap);
    }
}
// Make it so I can access this.request and this.response somehow
Thing.prototype = Object.create(AbstractThing); 

I can no longer access this.request.cookies because this is now called inside of the sendSoap closure. I don't know why javascript makes functions as objects but I'm getting slightly frustrated.

I've tried many, many things and can't figure out a way to do this and need to because the original call to foo is actually a recursive function I'm using in a state-itterator pattern to do authentication in a SOAP web service I've written in Java.

The last way that I can think of doing this is to modify the SOAP npm package so that I can pass this.cookies to createClient instead of just the callback.

I'm really all out of ideas. Any help would be greatly appreciated.

I am having a really, really hard time trying call an object function inside of an asynchronous soap request. It basically boils down to this:

function Thing(request, response) {

    this.foo = function() {
        console.log("this is foo");
    }

    this.doThing = function() {
        // Get SOAP args
        args = { foo: this.request.cookies.foo };
        // From the SOAP npm package library
        soap.createClient(function(err, client) {
            client.doSomething(args, function(err, result) {
                // Somehow call foo(); <--- CAN'T FIND A WAY TO DO THIS
            });
        });
    }
}
// Make it so I can access this.request and this.response somehow
Thing.prototype = Object.create(AbstractThing); 

I have tried many things, but I believe it fundamentally es down to the fact that I cannot call this.foo() inside any of the asychrenous soap functions. Although I can pass a callback function into createClient, like so:

function Thing(request, response) {

    this.foo = function() {
        console.log("this is foo");
    }

    this.sendSoap = function(err, client) {
        // Get SOAP args
        args = { 
            foo: this.request.cookies.foo <--- this.cookies undefined
        }; 
        client.doSomething(args, function(err, result) {
            // Somehow call foo(); <--- CAN'T FIND A WAY TO DO THIS
        });
    }

    this.doThing = function() {
        // From the SOAP npm package library
        soap.createClient(this.sendSoap);
    }
}
// Make it so I can access this.request and this.response somehow
Thing.prototype = Object.create(AbstractThing); 

I can no longer access this.request.cookies because this is now called inside of the sendSoap closure. I don't know why javascript makes functions as objects but I'm getting slightly frustrated.

I've tried many, many things and can't figure out a way to do this and need to because the original call to foo is actually a recursive function I'm using in a state-itterator pattern to do authentication in a SOAP web service I've written in Java.

The last way that I can think of doing this is to modify the SOAP npm package so that I can pass this.cookies to createClient instead of just the callback.

I'm really all out of ideas. Any help would be greatly appreciated.

Share Improve this question asked May 10, 2016 at 0:19 Alexander KleinhansAlexander Kleinhans 6,27813 gold badges66 silver badges119 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

The reason why is that this in the callback function will typically refer to the global window scope.

this is a mon source of pain in JS developers and more often than not it doesn't refer to what you think it may. You can search the full details online.

Why not closure it like this?

function Thing(request, response) {

    this.foo = function() {
        console.log("this is foo");
    }

    this.doThing = function() {
        var self = this; //Closure to the Thing function
        // Get SOAP args
        args = { foo: this.request.cookies.foo };
        // From the SOAP npm package library
        soap.createClient(function(err, client) {
            client.doSomething(args, function(err, result) {
                self.foo();
            });
        });
    }
}

Multiple options for a working solution.

A. Declaring nested functions as named functions, or assigning anonymous functions to named variable within the closure, allows nested functions to be called by any other function within the closure without using this. E.G.

// Either naming a function:
function foo () { console.log("foo") 
// or assigning it to a named variable:
var foo = function() { console.log("foo")};

allows the function be called as foo() inside the closure.

B. Declaring a variable set to the this value during Thing object construction allows functions within the closure to access their instance object using the variable name. This is the same technique contained in the answer from Philip:

`var self = this;`

C. Use anonymous arrow functions assigned to named variables. They can be called from other nested functions in the closure using the variable name. Arrow functions bind the this value from when and where they were declared. Hence arrow functions can access their Thing object instance using this without the need of a separate self variable alias. E.G.

var foo = () => {console.log(this.message)};
this.message = "foo was here";
foo();  // logs 'foo was here'

D. Of course set any parameters, nested functions or data values which must be accessed outside the closure as object properties.

// inside constructor
   var foo = () => { /* whatever */ }; // callable within closure as foo()
   this.foo = foo;
// outside constructor
   var thing = new Thing( arg1, arg2);
   thing.foo();                        // callable outside closure as thing.foo()

E) Parameters passed to Thing when called as a constructor are accessible within the closure simply by using the parameter name. For setting up a name value pair object from a request cookies object you may need an object initialiser without this

    args = { 
        foo: request.cookies.foo // request is a parameter
    };
发布评论

评论列表(0)

  1. 暂无评论