如何在回调中访问正确的“this”

How to access the correct `this` inside a callback

提问人:Felix Kling 提问时间:11/29/2013 最后编辑:Peter MortensenFelix Kling 更新时间:4/12/2023 访问量:619721

问:

我有一个构造函数,它注册了一个事件处理程序:

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', function () {
        alert(this.data);
    });
}

// Mock transport object
var transport = {
    on: function(event, callback) {
        setTimeout(callback, 1000);
    }
};

// called as
var obj = new MyConstructor('foo', transport);

但是,我无法在回调中访问所创建对象的属性。看起来它不是指创建的对象,而是另一个对象。datathis

我还尝试使用对象方法而不是匿名函数:

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', this.alert);
}

MyConstructor.prototype.alert = function() {
    alert(this.name);
};

但它也表现出同样的问题。

如何访问正确的对象?

javascript 回调 这个

评论

0赞 Bergi 3/1/2014
相关:在 JavaScript 原型函数中保留对“this”的引用
0赞 Bergi 9/10/2014
相关:使用 JavaScript 原型对象时事件方法中的“this”关键字
5赞 Ondra Žižka 2/2/2017
关于这个有用的 TypeScript 页面,主要也适用于 JS。
8赞 Felix Kling 11/22/2020
@strattonn:自我回答问题是UI中的一个选项,并鼓励:stackoverflow.blog/2011/07/01/...。对于一遍又一遍地出现的问题,我做了几次,以提供一个规范的答案。规范问答的问题在于,现有问题通常没有以足够笼统的方式表达,无法专注于核心问题。

答:

2283赞 Felix Kling 11/29/2013 #1

你应该知道什么this

this(又名“上下文”)是每个函数中的一个特殊关键字,其值仅取决于函数的调用方式,而不取决于函数的定义方式/时间/位置。它不像其他变量那样受到词法范围的影响(箭头函数除外,见下文)。以下是一些示例:

function foo() {
    console.log(this);
}

// normal function call
foo(); // `this` will refer to `window`

// as object method
var obj = {bar: foo};
obj.bar(); // `this` will refer to `obj`

// as constructor function
new foo(); // `this` will refer to an object that inherits from `foo.prototype`

要了解更多信息,请查看 MDN 文档this


如何参考正确的this

使用箭头函数

ECMAScript 6 引入了箭头函数,可以将其视为 lambda 函数。它们没有自己的绑定。相反,在作用域中查找,就像普通变量一样。这意味着您不必致电 .这不是他们唯一的特殊行为,请参考 MDN 文档了解更多信息。thisthis.bind

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', () => alert(this.data));
}

请勿使用this

您实际上不想特别访问它所指的对象。这就是为什么一个简单的解决方案是简单地创建一个也引用该对象的新变量。变量可以具有任何名称,但常见的名称是 和 。thisselfthat

function MyConstructor(data, transport) {
    this.data = data;
    var self = this;
    transport.on('data', function() {
        alert(self.data);
    });
}

由于是一个普通变量,因此它遵循词法范围规则,并且可以在回调中访问。这样做还有一个优点,即您可以访问回调本身的值。selfthis

显式设置回调 - 第 1 部分this

看起来您无法控制 的值,因为它的值是自动设置的,但实际上并非如此。this

每个函数都有 .bind [docs] 方法,该方法返回一个绑定到值的新函数。该函数的行为与您调用的函数完全相同,只是该函数是由您设置的。无论以何种方式或何时调用该函数,都将始终引用传递的值。this.bindthisthis

function MyConstructor(data, transport) {
    this.data = data;
    var boundFunction = (function() { // parenthesis are not necessary
        alert(this.data);             // but might improve readability
    }).bind(this); // <- here we are calling `.bind()` 
    transport.on('data', boundFunction);
}

在本例中,我们将回调绑定到 的值 。thisMyConstructorthis

注意:当 jQuery 的绑定上下文时,请改用 jQuery.proxy [docs]。这样做的原因是,在取消绑定事件回调时,不需要存储对函数的引用。jQuery在内部处理。

回调集 - 第 2 部分this

一些接受回调的函数/方法也接受回调应引用的值。这基本上和自己绑定它一样,但函数/方法会为你做这件事。Array#map [docs] 就是这样一种方法。其签名是:this

array.map(callback[, thisArg])

第一个参数是回调,第二个参数是应该引用的值。下面是一个人为的例子:this

var arr = [1, 2, 3];
var obj = {multiplier: 42};

var new_arr = arr.map(function(v) {
    return v * this.multiplier;
}, obj); // <- here we are passing `obj` as second argument

注意:是否可以传递值通常在该函数/方法的文档中提及。例如,jQuery 的 $.ajax 方法 [docs] 描述了一个名为 :thiscontext

此对象将成为所有与 Ajax 相关的回调的上下文。


常见问题:使用对象方法作为回调/事件处理程序

此问题的另一个常见表现是将对象方法用作回调/事件处理程序时。函数是 JavaScript 中的一等公民,术语“方法”只是作为对象属性值的函数的口语术语。但该函数没有指向其“包含”对象的特定链接。

请看以下示例:

function Foo() {
    this.data = 42,
    document.body.onclick = this.method;
}

Foo.prototype.method = function() {
    console.log(this.data);
};

该函数被指定为单击事件处理程序,但如果单击,则记录的值将为 ,因为在事件处理程序中,引用的是 ,而不是 的实例。
正如开头已经提到的,引用的内容取决于函数的调用方式,而不是函数的定义方式。
如果代码如下所示,则该函数没有对对象的隐式引用可能更明显:
this.methoddocument.bodyundefinedthisdocument.bodyFoothis

function method() {
    console.log(this.data);
}


function Foo() {
    this.data = 42,
    document.body.onclick = this.method;
}

Foo.prototype.method = method;

解决方案与上面提到的相同:如果可用,则用于显式绑定到特定值.bindthis

document.body.onclick = this.method.bind(this);

或者使用匿名函数作为回调/事件处理程序,将该函数作为对象的“方法”显式调用,并将对象 () 分配给另一个变量:this

var self = this;
document.body.onclick = function() {
    self.method();
};

或使用箭头函数:

document.body.onclick = () => this.method();

评论

51赞 vol7ron 9/12/2014
菲利克斯,我以前读过这个答案,但从未回复过。我越来越担心人们使用和引用 .我有这种感觉,因为在不同的上下文中使用了一个重载变量;而通常对应于本地实例,通常引用另一个对象。我知道你没有设置这个规则,因为我在其他地方看到它出现过,但这也是我开始使用 ,但不确定其他人的感受,除了导致的不统一做法。selfthatthisthisselfthat_this
0赞 zzzzBov 3/19/2015
@FelixKling,它允许你对像 和 这样的代码超级懒惰。$(...).on('click', $.proxy(obj, 'function'))$(...).off('click', obj.function)
6赞 Nolo 11/15/2016
@FelixKling 有时依赖 和 会很有用。特别是我得到了很多里程。我不太倾向于使用,也许只是出于习惯,尽管我知道(但不确定)与其他选项相比,使用 bind 可能会有轻微的开销优势。Function.prototype.call ()Function.prototype.apply ()apply ()bind ()
3赞 Jack_Hu 6/7/2022
需要注意的是,这将对在解释过程中首次遇到的上下文进行快照......也就是说,当 JavaScript 第一次到达函数时,它将在此时获取上下文!这可能变得难以排除故障,因为无法更改 CAN 的标准实现。一旦函数绑定到另一个对象,它就会一直绑定到该对象,尝试重新绑定它将不起作用。bind()bind()thisbind()
74赞 Guffa 5/21/2014 #2

这一切都在调用方法的“神奇”语法中:

object.property();

当您从对象中获取属性并一次性调用它时,该对象将成为该方法的上下文。如果调用相同的方法,但在单独的步骤中,则上下文是全局范围(窗口):

var f = object.property;
f();

获取方法的引用后,它不再附加到对象。它只是对普通函数的引用。当您获取要用作回调的引用时,也会发生同样的情况:

this.saveNextLevelData(this.setAll);

这就是将上下文绑定到函数的位置:

this.saveNextLevelData(this.setAll.bind(this));

如果您使用的是 jQuery,则应改用该方法,因为并非所有浏览器都支持该方法:$.proxybind

this.saveNextLevelData($.proxy(this.setAll, this));
38赞 RobG 6/1/2014 #3

“上下文”的麻烦

术语“上下文”有时用于指代 this 引用的对象。它的使用是不恰当的,因为它在语义上或技术上都不符合 ECMAScript 的 this

“上下文”是指围绕事物增加意义的情况,或一些赋予额外意义的前后信息。术语“上下文”在 ECMAScript 中用于指代执行上下文,即所有参数、作用域,以及某些执行代码范围内的参数。

这在 ECMA-262 第 10.4.2 节中显示:

将 ThisBinding 设置为与 ThisBinding 相同的值 调用执行上下文

这清楚地表明这是执行上下文的一部分。

执行上下文提供周围信息,为正在执行的代码添加意义。它包含的信息比 thisBinding 多得多。

的价值不是“上下文”。它只是执行上下文的一部分。它本质上是一个局部变量,可以通过调用任何对象来设置,在严格模式下,可以设置为任何值。

评论

0赞 Roamer-1888 6/8/2019
不同意这个答案。“执行语境”一词的存在并不禁止“语境”的其他用法,就像它禁止“执行”的其他用法一样。也许有一个更好的术语来描述,但这里没有提供,可以说现在关上“上下文”的大门为时已晚。this
0赞 RobG 6/9/2019
@Roamer-1888 - 感谢您的编辑。你是对的,但我的论点并不依赖于“执行上下文”的存在,从而排除了“上下文”用于其他目的。相反,它基于“上下文”从技术和语义角度来看都是不合适的。我还认为使用“上下文”而不是“这个”正在消亡。我看不出有任何理由找到这个或这个绑定的替代术语,它只是混淆了,意味着在某些时候你必须解释“上下文”实际上是这个,而且它无论如何都不在“上下文”中。:-)
0赞 Roamer-1888 6/9/2019
我不认为你可以说绝不是“上下文”,当你已经承认它是执行上下文的一部分时,“执行”只是形容词。
0赞 RobG 6/9/2019
@Roamer-1888——我不打算继续这个谈话。是的,这是执行上下文的一部分。说这是上下文,就像说一个团队的一名球员就是团队一样。
273赞 Mohan Dere 8/13/2016 #4

以下是访问子上下文中的父上下文的几种方法:

  1. 您可以使用该函数。bind()
  2. 将对 context/this 的引用存储在另一个变量中(请参阅以下示例)。
  3. 使用 ES6 箭头函数。
  4. 更改代码、函数设计和架构 - 为此,您应该能够控制 JavaScript 中的设计模式

1. 使用功能bind()

function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data', ( function () {
        alert(this.data);
    }).bind(this) );
}
// Mock transport object
var transport = {
    on: function(event, callback) {
        setTimeout(callback, 1000);
    }
};
// called as
var obj = new MyConstructor('foo', transport);

如果您使用的是下划线.js - http://underscorejs.org/#bind

transport.on('data', _.bind(function () {
    alert(this.data);
}, this));

2. 将对 context/this 的引用存储在另一个变量中

function MyConstructor(data, transport) {
  var self = this;
  this.data = data;
  transport.on('data', function() {
    alert(self.data);
  });
}

3.箭头功能

function MyConstructor(data, transport) {
  this.data = data;
  transport.on('data', () => {
    alert(this.data);
  });
}

评论

1赞 Stav Bodik 3/13/2019
bind() 选项令人惊叹,它只是将这个对象的指针传递给另一个对象上的 this(:谢谢!
0赞 RobG 3/29/2021
"子上下文中的父上下文“是一个误导性短语,因为这不是父/子关系的一部分。它通常指调用方法的对象,但可以是任何对象,也可以是严格模式下的任何值。“上下文”是指由于 ECMA-262 禁止引用而无法引用的执行上下文这是许多参数中的一个)。
30赞 AL-zami 8/19/2017 #5

首先,您需要清楚地了解 this 关键字在 scope 上下文中的范围和行为。

这个范围(&):


JavaScript 中有两种类型的作用域。他们是:

  1. 全球范围

  2. 功能范围

简而言之,全局范围是指窗口对象。在全局范围内声明的变量可以从任何位置访问。

另一方面,函数作用域位于函数内部。函数内部声明的变量无法正常从外部世界访问。

全局范围内的 this 关键字是指 window 对象。函数内部的这也指 window 对象。因此,这将始终引用窗口直到我们找到一种方法来操作以指示我们自己选择的上下文。

--------------------------------------------------------------------------------
-                                                                              -
-   Global Scope                                                               -
-   (globally "this" refers to window object)                                  -
-                                                                              -
-   function outer_function(callback){                                         -
-                                                                              -
-       // Outer function scope                                                -
-       // Inside the outer function, the "this" keyword                       -
-       //  refers to window object                                            -
-       callback() // "this" inside callback also refers to the  window object -
-   }                                                                          -
-                                                                              -
-   function callback_function(){                                              -
-                                                                              -
-       // Function to be passed as callback                                   -
-                                                                              -
-       // Here "THIS" refers to the window object also                        -
-   }                                                                          -
-                                                                              -
-   outer_function(callback_function)                                          -
-   // Invoke with callback                                                    -
-                                                                              -
--------------------------------------------------------------------------------

在回调函数中操作的不同方法:

在这里,我有一个名为 Person 的构造函数。它有一个名为 name 的属性和四个名为 sayNameVersion1、sayNameVersion2、sayNameVersion3 和 sayNameVersion4 的方法。他们四个人都有一个特定的任务。接受回调并调用它。回调有一个特定的任务,即记录 Person 构造函数实例的 name 属性。

function Person(name){

    this.name = name

    this.sayNameVersion1 = function(callback){
        callback.bind(this)()
    }
    this.sayNameVersion2 = function(callback){
        callback()
    }

    this.sayNameVersion3 = function(callback){
        callback.call(this)
    }

    this.sayNameVersion4 = function(callback){
        callback.apply(this)
    }

}

function niceCallback(){

    // Function to be used as callback

    var parentObject = this

    console.log(parentObject)
}

现在,让我们从 person 构造函数创建一个实例,并使用 niceCallback 调用不同版本的 sayNameVersionX(X 指的是 1,2,3,4)方法,看看我们可以通过多少种方式来操作 this 内部回调来引用 person 实例。

var p1 = new Person('zami') // Create an instance of Person constructor

捆:

bind 的作用是创建一个新函数,并将 this 关键字设置为提供的值。

sayNameVersion1并使用 bind 来操作调函数。sayNameVersion2

this.sayNameVersion1 = function(callback){
    callback.bind(this)()
}
this.sayNameVersion2 = function(callback){
    callback()
}

第一个通过方法本身内部的回调将其绑定。对于第二个,回调是与绑定到它的对象一起传递的。

p1.sayNameVersion1(niceCallback) // pass simply the callback and bind happens inside the sayNameVersion1 method

p1.sayNameVersion2(niceCallback.bind(p1)) // uses bind before passing callback

叫:

调用方法的第一个参数在附加了调用的函数中用作参数。

sayNameVersion3使用 call 来操作 this 来引用我们创建的 person 对象,而不是 window 对象。

this.sayNameVersion3 = function(callback){
    callback.call(this)
}

它的称呼如下:

p1.sayNameVersion3(niceCallback)

应用:

call 类似,apply 的第一个参数是指将由 this 关键字指示的对象。

sayNameVersion4使用 apply 来操作来引用 person 对象

this.sayNameVersion4 = function(callback){
    callback.apply(this)
}

它的称呼如下。只需传递回调,

p1.sayNameVersion4(niceCallback)

评论

1赞 AL-zami 8/19/2017
任何关于答案的建设性批评将不胜感激!
1赞 Randall Flagg 5/23/2018
全局范围内的 this 关键字不一定引用 window 对象。这仅在浏览器中是正确的。
1赞 AL-zami 7/9/2018
@RandallFlagg我从浏览器的角度写了这个答案。如有必要,可以自由地回答这个答案:)
24赞 Datta Chanewad 11/17/2017 #6

我们不能将其绑定到 ,因为它总是与全局对象 (Window) 一起执行。如果你想在回调函数中访问上下文,那么通过使用回调函数,我们可以实现它:setTimeout()thisbind()

setTimeout(function(){
    this.methodName();
}.bind(this), 2000);

评论

0赞 Peter Mortensen 7/26/2021
回复“”:不是“”(小写)吗?Windowwindow
5赞 Andrea Puddu 8/28/2018 #7

另一种方法是接口中的方法,这是自 DOM2 以来在事件侦听器中绑定的标准方法,它允许您始终删除侦听器(以及其他好处):thishandleEvent(evt)EventListener

var obj = {
  handleEvent(e) {
    // always true
    console.log(this === obj);
  }
};

document.body.addEventListener('click', obj);

有关使用的详细信息可以在这里找到: DOM handleEvent:自 2000 年以来的跨平台标准handleEvent

评论

0赞 kdubs 4/6/2023
我非常喜欢这个。首先,我见过这个。感谢您指出这一点。
9赞 skyboyer 9/22/2018 #8

目前,如果在代码中使用类,还有另一种方法。

类字段的支持下,可以通过以下方式实现:

class someView {
    onSomeInputKeyUp = (event) => {
        console.log(this); // This refers to the correct value
    // ....
    someInitMethod() {
        //...
        someInput.addEventListener('input', this.onSomeInputKeyUp)

可以肯定的是,在引擎盖下,绑定上下文的所有旧好箭头函数,但在这种形式下,它看起来比显式绑定更清晰。

由于这是一个第 3 阶段的提案,因此您现在(2018 年 8 月)需要 Babel 和适当的 Babel 插件来处理它。

评论

2赞 yeyeyerman 2/18/2019
这正是我在 Typescript 中让它工作的方式:在类中。public methodName = (params) => { body }
59赞 Ashish 1/30/2019 #9

你应该知道“这个”关键词。

根据我的观点,您可以通过三种方式实现“this”(Self|箭头功能|Bind 方法)

与其他语言相比,函数的关键字在 JavaScript 中的行为略有不同。this

它在严格模式和非严格模式之间也有一些区别。

在大多数情况下,此值由函数的调用方式决定。

在执行过程中无法通过赋值设置它,并且每次调用函数时都可能不同。

ES5 引入了 bind() 方法来设置函数的值,而不管它是如何调用的,this

ES2015 引入了箭头函数,这些函数不提供自己的绑定(它保留了封闭词法上下文的这个值)。this

方法1:Self - Self 用于维护对原始 this 的引用,即使上下文正在发生变化。这是事件处理程序中经常使用的一种技术(尤其是在闭包中)。

参考资料this

function MyConstructor(data, transport) {
    this.data = data;
    var self = this;
    transport.on('data', function () {
        alert(self.data);
    });
}

方法 2:箭头函数 - 箭头函数表达式在语法上是正则函数表达式的紧凑替代方法,尽管它没有与 this、arguments、super 或 new.target 关键字的绑定。

箭头函数表达式不适合用作方法,并且不能用作构造函数。

参考箭头函数表达式

  function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data',()=> {
        alert(this.data);
    });
}

方法 3:绑定 - bind() 方法创建一个新函数,该函数在调用时,其关键字设置为提供的值,并在调用新函数时提供的任何参数之前具有给定的参数序列。this

参考:Function.prototype.bind()

  function MyConstructor(data, transport) {
    this.data = data;
    transport.on('data',(function() {
        alert(this.data);
    }).bind(this);
14赞 Vikas 2/18/2019 #10

问题围绕着关键字在 JavaScript 中的行为方式。 行为不同,如下所示,thisthis

  1. 的值通常由函数执行上下文确定。this
  2. 在全局作用域中,指全局对象(对象)。thiswindow
  3. 如果为任何函数启用了严格模式,则 的值将与严格模式下一样,全局对象代替对象。thisundefinedundefinedwindow
  4. 点前的对象是关键字将绑定到的对象。this
  5. 我们可以用 、 和 显式设置 this 的值call()bind()apply()
  6. 当使用关键字(构造函数)时,这将绑定到正在创建的新对象。new
  7. 箭头函数不绑定,而是按词法绑定(即基于原始上下文)thisthis

正如大多数答案所建议的那样,我们可以使用箭头函数或 bind() 方法或 Self var。我会引用 Google JavaScript 风格指南中关于 lambdas(箭头函数)的观点

比起 f.bind(this),更喜欢使用箭头函数,尤其是在 goog.bind(f, 这个)。避免写 const self = this。箭头函数 对于回调特别有用,回调有时会意外传递 其他参数。

Google 明确推荐使用 lambda 而不是 bind 或 const self = this

因此,最好的解决方案是使用 lambda,如下所示:

function MyConstructor(data, transport) {
  this.data = data;
  transport.on('data', () => {
    alert(this.data);
  });
}

引用:

  1. https://medium.com/tech-tajawal/javascript-this-4-rules-7354abdb274c
  2. 箭头函数与绑定

评论

0赞 Felix Kling 2/19/2019
这个问题是关于使用函数/方法作为回调的。您的答案可能更适合 stackoverflow.com/q/3127429/218196
0赞 bleistift2 2/22/2020
我发现你的第四点措辞模棱两可。考虑示例“将带有此对象的方法用作回调的方法时出现的问题”,其中正确的对象位于点之前,但上下文仍然不是该对象。
5赞 Willem van der Veen 5/5/2020 #11

this在 JavaScript 中:

JavaScript 中的值 100% 取决于函数的调用方式,而不是函数的定义方式。我们可以通过“点法则的左边”相对容易地找到 的值:thisthis

  1. 当使用 function 关键字创建函数时,其值是被调用的函数点左侧的对象this
  2. 如果点上没有对象,那么函数内部的值通常是全局对象(在 Node.js 和浏览器中)。我不建议在这里使用关键字,因为它不如使用类似的东西那么明确!thisglobalwindowthiswindow
  3. 存在某些构造,如箭头函数和使用 a 函数创建的函数,这些函数可以固定 的值。这些是规则的例外,但它们对于修复 的值非常有帮助。Function.prototype.bind()thisthis

Node.js 中的示例

module.exports.data = 'module data';
// This outside a function in node refers to module.exports object
console.log(this);

const obj1 = {
    data: "obj1 data",
    met1: function () {
        console.log(this.data);
    },
    met2: () => {
        console.log(this.data);
    },
};

const obj2 = {
    data: "obj2 data",
    test1: function () {
        console.log(this.data);
    },
    test2: function () {
        console.log(this.data);
    }.bind(obj1),
    test3: obj1.met1,
    test4: obj1.met2,
};

obj2.test1();
obj2.test2();
obj2.test3();
obj2.test4();
obj1.met1.call(obj2);

输出:

Enter image description here

让我一一引导您完成输出(忽略从第二个开始的第一个日志):

  1. this正是因为左边的点法则,我们可以看到是怎么叫的。 是点的左边,因此是值。obj2test1obj2.test1();obj2this
  2. 即使位于点的左边,也通过方法绑定。值为 。obj2test2obj1bind()thisobj1
  3. obj2是调用的函数的点的左侧:。因此,将是 的值。obj2.test3()obj2this
  4. 在本例中:是点的左边。但是,箭头函数没有自己的绑定。因此,它将绑定到外部范围的值,该范围是一开始记录的对象。obj2.test4()obj2thisthismodule.exports
  5. 我们还可以使用函数指定 的值。在这里,我们可以将所需的值作为参数传入,在这种情况下。thiscallthisobj2
5赞 Md. Tazbir Ur Rahman Bhuiyan 10/13/2020 #12

我遇到了一个折线图函数的问题,该函数是从 HTML 调用的,如下所示: .NgxxAxisTickFormatting[xAxisTickFormatting]="xFormat"

我无法从声明的函数访问组件的变量。这个解决方案帮助我解决了这个问题,找到了正确的方法。

而不是像这样使用函数:

xFormat (value): string {
  return value.toString() + this.oneComponentVariable; //gives wrong result
}

使用这个:

 xFormat = (value) => {
   // console.log(this);
   // now you have access to your component variables
   return value + this.oneComponentVariable
 }
4赞 Josh McGee 6/25/2021 #13

其他一些人已经谈到了如何使用 .bind() 方法,但具体来说,如果有人无法让它们一起工作,您可以将其与 .then() 一起使用:

someFunction()
.then(function(response) {
    //'this' wasn't accessible here before but now it is
}.bind(this))

如评论中所述,另一种方法是使用没有自己的“this”值的箭头函数

someFunction()
.then((response)=>{
    //'this' was always accessible here
})

评论

0赞 Felix Kling 6/25/2021
这是不正确的。(1) 箭头函数没有自己的值,而是使用关闭环境的值。(2)因此,对箭头功能没有影响。thisthis.bind
0赞 Josh McGee 6/25/2021
好电话,我复制了错误的代码,更新以显示两种变体
-1赞 ejectamenta 3/24/2023 #14

这就是我解决问题的方式

class myClass
{
    constructor(parent)
    {
        this.callback = (function() { 
            this.callbackFunctionOfParent();             
        }).bind(parent);
    }

    callCallback() {
         this.callback();
    }
}

class Class2
{
       constructor()
       {
            this.Name = "CLASS 2";

            this.test = new myClass(this);

            this.test.callCallback();
       } 

       callbackFunctionOfParent()
       {
           console.log("parent is: " + this.Name);
       }
}

var c2 = new Class2;

评论

1赞 Felix Kling 5/10/2023
这太复杂了。至少你可以写,但我相信这可以简化得多,这取决于你实际想要实现的目标。this.callback = function() { parent.callbackFunctionOfParent() }
0赞 ejectamenta 5/12/2023
问题在于在派生类的上下文中访问“this”,而不是在父类上调用函数的最简单方法是什么。
1赞 Felix Kling 5/12/2023
但是,为什么要提出一个更难理解的解决方案呢?解决方案应减少到绝对最低限度,以便易于理解。根据你的论点,我可以为“如何将两个数字相加”的问题提供以下解决方案,就可以了吗?function mul(x, y) { return x * y; } function add(x, y) { return mul(x, 1) + mul(y, 1); }; add(41, 1)
0赞 ejectamenta 5/15/2023
我认为您可以自由编辑帖子并使其更简洁,如果它仍然可以理解并在“运行代码片段”上给出相同的结果,那么我对此没有问题。
1赞 Arun s 4/12/2023 #15

您可以使用箭头函数来避免此问题。

const functionToTest = (dataToSet , transport) => {
  this.dataToSet = dataToSet ;
  transport.on('dataToSet ', () => {
    console.log(this.dataToSet);
  });
}