当前位置: 首页 > 知识库问答 >
问题:

调用ES6方法时绑定上下文。如何从称为回调的方法内访问对象?

轩辕修能
2023-03-14

我正试图了解ES6中类的语法。同时通过Bonnie Eisenman的学习反应母语学习织物母语。

我遇到了一个问题,在回调中访问this,当回调是一个Class方法时。我知道回调中的词汇this问题已经在StackOverflow上多次提出。例如,如何访问回调中正确的this上下文?。

根据我在网上的研究,我找到了一个解决方案。但我不确定在ES6中这样做是否正确。

当我尝试以下操作时,出现了我的问题:

class WeatherProject extends Component {
  constructor(props) {
    super(props);
    this.state = {
      zip: ''
    };
  }

  _handleTextChange(event) {
    console.log(event.nativeEvent.text);
    this.setState({zip: event.nativeEvent.text})
  }

  render() {
    return (
      <TextInput
        style={styles.input}
        onSubmitEditing={this._handleTextChange}/>
    );
  }
}

(我只是从书中的示例中稍微修改了它,以匹配ES6类语法和导入/导出语法,而不是Require。)

如果执行此操作,则\u handleTextChange中的this未定义(无法读取未定义的属性“setState”)。我对此感到惊讶。来自其他OO语言,我解释这个方法的行为更像是一个静态方法。

我已经能够通过跳过类方法并使用箭头表示法来解决这个问题。onSubmit编辑={事件=

不过,我真的很想知道如何调用类方法。经过一段时间的研究,我已经通过以下方式使其工作:onSubmitEditing={this.\u handleTextChange.bind(this)}。也许我误解了JavaScript的一个基本方面(我是JS的初学者),但这在我看来完全是疯了。如果不将对象显式绑定回方法,是否真的无法从方法中访问对象的上下文。。。它是自己的方法,在调用它的地方?

我还尝试添加var self=this ,并在\u handleTextChange中调用self.setState。但我发现这不起作用并不感到惊讶。

当对象作为回调调用时,从其方法之一中访问对象的正确方式是什么?


共有3个答案

南宫浩皛
2023-03-14

也许我误解了JavaScript的一个基本方面(我是JS的初学者),但这对我来说似乎完全疯狂。真的没有办法从方法中访问对象的上下文,而不显式地将对象绑定回...它自己的方法,在调用它的时候?

在javascript中,“方法”不属于对象。所有函数都是一级值(对象),而不是对象或类的“一部分”。

值的绑定在调用函数时发生,具体取决于调用函数的方式。具有方法表示法的函数调用将其this设置为接收对象,事件侦听器调用将其this设置为当前事件目标,而正常函数调用仅具有未定义的

如果您正在访问实例上的方法,它实际上只是生成函数的标准原型继承属性访问,然后调用该函数并动态绑定到接收器。

如果您想在实例是事件侦听器时将函数作为方法调用,则需要显式创建一个执行此操作的函数——“绑定”方法。在ES6中,通常首选箭头表示法。

谭彦
2023-03-14

脱离ES6,在常规的旧JavaScript中,当您传递对象的方法时,它只是对函数本身的引用,而不是对对象和函数的引用。

任何调用函数都可以通过正常调用函数来选择使用隐式this,甚至可以选择使用.call.apply.bind更改上下文。

var O = {
  foo: function () {
    console.log(this);
  },
  bar: 51
};

O.foo(); // `this` is O, the implicit context, inferred from the object host

var foo = O.foo;

foo(); // `this` is is the global object, or undefined in Strict Mode
朱慈
2023-03-14
匿名用户

React.create类(ES5)创建类的方式有一个内置功能,自动将所有方法绑定到此。但是当在ES6中引入并迁移React.create类时,他们发现对于在其他类中不习惯此功能的JavaScript开发人员来说,这可能有点混乱,或者当他们从React转移到其他类。

因此,他们决定不将此内置到React的类模型中。如果愿意,您仍然可以在构造函数中显式地预绑定方法

class WeatherProject extends Component {
  constructor(props) {
    super(props);
    this.state = {
      zip: ''
    };
    this._handleTextChange = this._handleTextChange.bind(this); //Binding to `this`
  }

  _handleTextChange(event) {
    console.log(event.nativeEvent.text);
    this.setState({zip: event.nativeEvent.text})
  }

但是我们总是有一个简单的方法来避免这种预绑定。是 啊你明白了。箭头功能。

class WeatherProject extends Component {
  constructor(props) {
    super(props);
    this.state = {
      zip: ''
    };
  }

  _handleTextChange = event => {
    console.log(event.nativeEvent.text);
    this.setState({zip: event.nativeEvent.text})
  }

  render() {
    return (
      <TextInput
        style={styles.input}
        onSubmitEditing={this._handleTextChange}/>
    );
  }
}

顺便说一句,这都是关于反应的。ES6类始终有一种从方法中访问对象上下文的方法,而无需将对象显式绑定回它自己的方法。

class bindTesting {
  constructor() {
    this.demo = 'Check 1';
  }

  someMethod() {
    console.log(this.demo);
  }

  callMe() {
    this.someMethod();
  }
}

let x = new bindTesting();
x.callMe(); //Prints 'Check 1';

但如果我们在JSX表达式中调用它,它不会打印“check1”。

EDIT::正如@Oka所提到的,类主体中的箭头函数是ES7的特性,在编译器/多填充(如babel)中可用。如果您不使用支持此功能的transpiler,我们可以如上所述绑定到此,或者像这样编写一个新的BaseComponent(这是个坏主意)

class BaseComponent extends React.Component {
 _bind(...methods) {
  methods.forEach( (method) => this[method] = this[method].bind(this) );
 }
}

class ExampleComponent extends BaseComponent {
 constructor() {
  super();
  this._bind('_handleTextChange', '_handleClick');
 }
 // ...
}

 类似资料:
  • 问题内容: 如果我有两个变量: 在不知道的类的情况下obj,如何调用由其标识的方法methodName? 被调用的方法没有参数,并且有String返回值。 问题答案: 参数标识你需要的非常特定的方法(如果有多个重载可用,如果该方法没有参数,则仅给出methodName)。 然后,你通过调用该方法 同样,.invoke如果没有,请忽略中的参数。

  • 问题内容: 我的模板看不到从Spring传递过来的对象。 我的代码: Contoller的代码: 主模板的代码: 片段的代码: 结果,我看到了方法调用的代码,例如 为什么thymeleaf不调用方法,而是在输出页上打印此文本?在http://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html的示例中,方法调用具有相同的语法,例如 相同的代

  • 我目前正在使用OpenGL和GLFW开发一个跨平台的2D渲染引擎。我有一个名为GameWindow的基本窗口类,以及一个名为Game的继承GameWindow的类。游戏覆盖了基类中的一些虚拟方法,以便GameWindow可以处理帧限制等。在GameWindow的构造函数中,我使用glfwSetWindowSizeCallback指定窗口调整大小时要运行的方法。然后,此方法调用GameWindow的

  • 问题内容: 尝试在Parent类中创建1个接口和2个具体类。这将使封闭类成为内部类。 现在,我真的不确定如何在静态main()方法中创建C类的对象并调用C类的call()方法。现在我遇到了问题: 问题答案: 这里的内部类不是静态的,因此您需要创建一个外部类的实例,然后调用new, 但是在这种情况下,您可以将内部类设为静态, 那就可以使用了

  • 问题内容: 我在调用 非静态 方法时感到困惑 我知道 method-1 和 method-2 都将调用 doThis() ,但是功能上有什么区别吗? 问题答案: 功能上有区别吗? 两者的行为方式相同。 第二个选项不允许您再次重用该实例。在单行return语句中可能很方便和简洁(例如,请考虑使用构建器模式,其中每个构造方法都将返回一个半初始化的实例): 或者创建一个对象仅执行一次定义的操作。 方法2

  • 问题内容: 像这样:类具有一个称为sayHello()的方法。当该类的实例调用sayHello()时,另一个类中的方法会在调用sayHello()之前自动调用。 示例代码可以像这样: 输出结果: 似乎可以通过使用代理模式来完成。但我希望它可以更简单。 使用注释: 然后将MethodListener注释放在Person类中的方法sayHello()上, 调用具有MethodListener批注的方法