hi,你好!欢迎访问本站!登录
本站由简数采集腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 文章 - 后端开发 - 正文 看Cosplay古风插画小姐姐,合集图集打包下载:炫龙网 · 炫龙图库

【WEB前端开辟】5种正确处理JS的this指向的体式格局

2019-11-27后端开发ki4网35°c
A+ A-

我喜好在JS中变动函数实行上下文的指向,也称为 this 指向。

比方,我们能够在类数组对象上运用数组要领:

const reduce = Array.prototype.reduce;

function sumArgs() {
  return reduce.call(arguments, (sum, value) => {
    return sum += value;
  });
}

sumArgs(1, 2, 3); // => 6

另一方面,this 很难把握。

我们常常会发明本身用的 this 指向不准确。下面的教你怎样简朴地将 this 绑定到所需的值。

【相干课程引荐:JavaScript视频教程】

在最先之前,我须要一个辅佐函数execute(func),它仅实行作为参数供应的函数。

function execute(func) {
  return func();
}

execute(function() { return 10 }); // => 10

如今,继承明白缭绕this毛病的实质:要领星散。

1. 要领星散题目

假设有一个类Person包括字段firstName和lastName。另外,它还有一个要领getFullName(),该要领返回这人的全名。以下所示:

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;

  this.getFullName = function() {
    this === agent; // => true
    return `${this.firstName} ${this.lastName}`;
  }
}

const agent = new Person('前端', '小智');
agent.getFullName(); // => '前端 小智'

能够看到Person函数作为组织函数被挪用:new Person('前端', '小智')。 函数内部的 this 示意新创建的实例。

getfullname()返回这人的全名:'前端 小智'。正如预期的那样,getFullName()要领内的 this 即是agent。

假如辅佐函数实行agent.getFullName要领会发作什么:

execute(agent.getFullName); // => 'undefined undefined'

实行效果不准确:'undefined undefined',这是 this 指向不准确致使的题目。

如今在getFullName() 要领中,this的值是全局对象(浏览器环境中的 window )。 this 即是 window,${window.firstName} ${window.lastName} 实行效果是 'undefined undefined'。

发作这类状况是由于在挪用execute(agent.getFullName)时该要领与对象星散。 基本上发作的只是通例函数挪用(不是要领挪用):

execute(agent.getFullName); // => 'undefined undefined'

// 等价于:

const getFullNameSeparated = agent.getFullName;
execute(getFullNameSeparated); // => 'undefined undefined'

这个就是所谓的要领从它的对象中星散出来,当要领被星散,然后实行时,this 与原始对象没有衔接。

1、为了确保要领内部的this指向准确的对象,必需如许做

2、以属性接见器的情势实行要领:agent.getFullName()或许静态地将this绑定到包括的对象(运用箭头函数、.bind()要领等)

要领星散题目,以及由此致使this指向不准确,平常会在下面的几种状况中涌现:

回调

// `methodHandler()`中的`this`是全局对象
setTimeout(object.handlerMethod, 1000);

在设置事宜处置惩罚程序时

// React: `methodHandler()`中的`this`是全局对象
<button onClick={object.handlerMethod}>
  Click me
</button>

接着引见一些有用的要领,即假如要领与对象星散,怎样使this指向所需的对象。

2. 封闭上下文

坚持this指向类实例的最简朴要领是运用一个分外的变量self:

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
  const self = this;
  this.getFullName = function() {
    self === agent; // => true
    return `${self.firstName} ${self.lastName}`;
  }
}
const agent = new Person('前端', '小智');
agent.getFullName();        // => '前端 小智'
execute(agent.getFullName); // => '前端 小智'

getFullName()静态地封闭self变量,有用地对this举行手动绑定。

如今,当挪用execute(agent.getFullName)时,一切事情一般,由于getFullName()要领内 this 老是指向准确的值。

3. 运用箭头函数

有无方法在没有附加变量的状况下静态绑定this? 是的,这正是箭头函数的作用。

运用箭头函数重构Person:

function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;

  this.getFullName = () => `${this.firstName} ${this.lastName}`;
}

const agent = new Person('前端', '小智');

agent.getFullName();        // => '前端 小智'
execute(agent.getFullName); // => '前端 小智'

箭头函数以词法体式格局绑定this。 简朴来讲,它运用来自其定义的外部函数this的值。

发起在须要运用外部函数上下文的一切状况下都运用箭头函数。

4. 绑定上下文

如今让我们更进一步,运用ES6中的类重构Person。

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

const agent = new Person('前端', '小智');

agent.getFullName();        // => '前端 小智'
execute(agent.getFullName); // => 'undefined undefined'

不幸的是,纵然运用新的类语法,execute(agent.getFullName)依然返回“undefined undefined”。

在类的状况下,运用附加的变量self或箭头函数来修复this的指向是行不通的。

但是有一个触及bind()要领的技能,它将要领的上下文绑定到组织函数中:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;

    this.getFullName = this.getFullName.bind(this);
  }

  getFullName() {
    return `${this.firstName} ${this.lastName}`;
  }
}

const agent = new Person('前端', '小智');

agent.getFullName();        // => '前端 小智'
execute(agent.getFullName); // => '前端 小智'

组织函数中的this.getFullName = this.getFullName.bind(this)将要领getFullName()绑定到类实例。

execute(agent.getFullName) 按预期事情,返回'前端 小智'。

5. 胖箭头要领

bind 体式格局有点太甚冗杂,我们能够运用胖箭头的体式格局:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  getFullName = () => {
    return `${this.firstName} ${this.lastName}`;
  }
}

const agent = new Person('前端', '小智');

agent.getFullName();        // => '前端 小智'
execute(agent.getFullName); // => '前端 小智'

胖箭头要领getFullName =() =>{…}绑定到类实例,纵然将要领与其对象星散。

这类要领是在类中绑定this的最有用和最简约的要领。

6. 总结

与对象星散的要领会发生 this 指向不准确题目。静态地绑定this,能够手动运用一个附加变量self来保留准确的上下文对象。但是,更好的替换要领是运用箭头函数,其实质上是为了在词法上绑定this。

在类中,能够运用bind()要领手动绑定组织函数中的类要领。固然假如你不必运用 bind 这类冗杂体式格局,也能够运用简约轻易的胖箭头示意要领。

原文:https://github.com/valentinogagliardi/Little-JavaScript-Book/blob/v1.0.0/manuscript/chapter5.md

本文来自 js教程 栏目,迎接进修!

以上就是5种准确处置惩罚JS的this指向的体式格局的细致内容,更多请关注ki4网别的相干文章!

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  选择分享方式
  移步手机端
【WEB前端开辟】5种正确处理JS的this指向的体式格局

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
标签:

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>