在闭包内部调用父函数

Calling a parent function inside a closure

本文关键字:函数 调用 内部 闭包      更新时间:2023-09-26

我在异步soap请求中尝试调用对象函数时遇到了非常非常困难的问题。基本上可以归结为:

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

我已经尝试了很多方法,但我相信从根本上来说,这是因为我不能在任何异步soap函数中调用this.foo()。虽然我可以将回调函数传递到createClient,就像这样:

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

我无法再访问this.request.cookies,因为this现在在sendSoap闭包内部被调用。我不知道javascript为什么把函数作为对象,但我有点沮丧。

我已经尝试了很多很多事情,但都想不出实现这一点的方法,并且需要这样做,因为对foo的原始调用实际上是一个递归函数,我在状态指示器模式中使用它来在我用Java编写的SOAP web服务中进行身份验证。

我能想到的最后一种方法是修改SOAP npm包,这样我就可以将this.cookies传递给createClient,而不仅仅是回调。

我真的没有主意了。如有任何帮助,我们将不胜感激。

原因是回调函数中的this通常会引用全局窗口范围。

this在JS开发人员中是一个常见的痛苦来源,通常它并没有提到你认为它可能是什么。你可以在网上搜索完整的细节。

为什么不这样结束呢?

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

工作解决方案的多个选项

A。将嵌套函数声明为命名函数,或将匿名函数分配给闭包中的命名变量,可以让闭包中的任何其他函数在不使用this的情况下调用嵌套函数例如

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

允许函数在闭包内被调用为CCD_ 11。

B。在Thing对象构造期间声明一个设置为this值的变量允许闭包中的函数使用变量名访问其实例对象。这与Philip的回答中包含的技术相同:

`var self = this;`

C。使用分配给命名变量的匿名箭头函数。可以使用变量名从闭包中的其他嵌套函数调用它们。箭头函数从声明this值的时间和位置绑定它们。因此,箭头函数可以使用this访问其Thing对象实例,而不需要单独的self变量别名。例如

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

D。当然,将必须在闭包之外访问的任何参数、嵌套函数或数据值设置为对象属性。

// 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) 作为构造函数调用时传递给Thing的参数可以在闭包中通过使用参数名称进行访问。为了从请求cookie对象设置名称-值对对象,您可能需要一个不带this 的对象初始化程序

    args = { 
        foo: request.cookies.foo // request is a parameter
    };