首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ES6函数、箭头函数和ES6类中的“this”

ES6函数、箭头函数和ES6类中的“this”
EN

Stack Overflow用户
提问于 2018-02-22 05:18:08
回答 5查看 9K关注 0票数 8
代码语言:javascript
复制
class App extends Component {
  constructor(props) {
    ...
  }

  onChange = (e) => this.setState({term: e.target.value})

  onSubmit(e){
    e.preventDefault();
    const api_key = "C1hha1quJAQZf2JUlK";
    const url = `http://api.giphy.com/v1/gifs/search?q=${this.state.term}&api_key=${api_key}`;
  }

  render() {
    return (
      <div>
        <form onSubmit={this.onSubmit}>
          <input value={this.state.term} onChange={this.onChange}/>
          <button>Search!</button>
        </form>
      </div>
    );
  }
}

在类(onChange和onSubmit)中声明的两种类型的函数之间有什么区别。如果我将this.sate声明为类方法,但将其更改为箭头函数,则在const 中引用该方法时会出现错误。

我想知道在这两种情况下到底是如何处理‘这’的,

另外,我该怎么做呢?比如说,如果我想使用相同的onSubmit函数(ES6类方法),但是当我调用它(在form元素中)时想要处理它,我该如何做呢?

使用this.onSubmit.bind(这个)?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2018-02-22 05:37:34

重要的是要知道这个语法:

代码语言:javascript
复制
class A {
  method = () => {}
}

只是用于在类构造函数中创建实例方法的语法糖:

代码语言:javascript
复制
class A {
  constructor() {
    this.method = () => {}
  }
}

注意:这个语法还不是JavaScript语言(目前处于第三阶段)的正式部分,所以您必须使用像Babel这样的调音员来处理它

thismethod中的值是类A,因为这是this在构造函数中所指向的(因为箭头函数从它们定义的范围继承上下文):

代码语言:javascript
复制
class A {
  constructor() {
    this.method = () => this;
  }
}

const instance = new A();
console.log(instance.method() === instance); // true

在类上定义一个常规(非箭头函数)方法会在类原型(不是实例)上创建一个方法,但是没有设置this的规则(因为this在JS和取决于如何调用函数,而不是如何定义函数中是动态的)。

代码语言:javascript
复制
class A {
  method() {}
}

console.log(new A().method === A.prototype.method); // true

如果在类实例上(通过.)调用以上述任何一种方式定义的方法,按照调用函数作为对象的方法时this如何绑定的规则,this将在这两种情况下指向类实例:

代码语言:javascript
复制
class A {
  constructor() {
    this.methodOnInstance = () => this;
  }
  methodOnPrototype() { return this; }
}

const instance = new A();
console.log(
  instance.methodOnInstance() === instance.methodOnPrototype(), // true
  instance.methodOnPrototype() === instance // true
);

上述两个方法声明的一个主要区别是,实例方法的this 总是将固定在类实例上,而类(prototype)方法没有(我们可以通过使用Function.prototype.applyFunction.prototype.call来更改它)。

代码语言:javascript
复制
class A {
  constructor() {
    this.methodOnInstance = () => this;
  }
  methodOnPrototype() { return this; }
}

const instance = new A();
console.log(
  instance.methodOnInstance() === instance.methodOnPrototype(), // true
  instance.methodOnPrototype.call('new this') === 'new this' // true
);

事件处理程序中经常发生this更改,其中事件处理程序调用传递给它的函数,并将上下文绑定到事件发生的元素(因此重写this值作为单击的元素或任何事件)。

这在所有(合成) DOM事件处理程序的React中也会发生。

因此,如果我们希望我们的方法的上下文总是指向React组件的实例,我们可以使用实例方法。

另一种限制上下文但不使用需要Babel的特殊实例方法语法的方法是,通过使用绑定上下文(使用Function.prototype.bind)从类(原型)方法直接创建实例方法:

代码语言:javascript
复制
class A {
  constructor() {
    this.methodOnInstance = this.methodOnPrototype.bind(this);
  }
  methodOnPrototype() { return this; }
}

const instance = new A();
console.log(
  instance.methodOnInstance() === instance.methodOnPrototype(), // true
  instance.methodOnPrototype() === instance // true
);

这允许我们使用特殊的实例方法语法,但使用当前可用的工具(ES2017和us )来达到相同的结果。

如果出于某种原因,我们想要一个总是绑定到类的实例的方法,我们也可以这样做:

代码语言:javascript
复制
class A {
  constructor() {
    this.method = this.method.bind(console);
  }
  method() { return this; }
}

const instance = new A();
console.log(
  instance.method() === console // true
);

票数 25
EN

Stack Overflow用户

发布于 2018-02-22 05:20:36

箭头函数表达式的语法比函数表达式短,并且没有它自己的这些函数表达式最适合于非方法函数,它们不能用作构造函数。

箭头函数通过词汇绑定它们的上下文,因此这实际上是指原始上下文。

在ES3/4函数声明中,可以通过存储在其他变量中使用this

代码语言:javascript
复制
const that = this;
onSubmit(e){
    e.preventDefault();
    const api_key = "***************";
    const url = `http://api.giphy.com/v1/gifs/search?q=${that.state.term}&api_key=${api_key}`;
  }
票数 1
EN

Stack Overflow用户

发布于 2018-02-22 05:23:37

另外,我该怎么做呢?比如说,如果我想使用相同的onSubmit函数(ES6类方法),但是当我调用它(在form元素中)时想要处理它,我该如何做呢? 使用this.onSubmit.bind(这个)?

是的,必须将方法绑定到构造函数中的组件。这是因为箭头函数会自动绑定到类,因此在方法中设置了该函数的范围。虽然onSubmit是一个尚未绑定的正则函数,但是方法中的这个函数将引用函数而不是组件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48920135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档