博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
this 上下文_当“ this”失去上下文时该怎么办
阅读量:2525 次
发布时间:2019-05-11

本文共 7174 字,大约阅读时间需要 23 分钟。

this 上下文

was named one of the !

被评为

The best way to avoid this losing context is to not use this at all. However, this is not always an option. We may have inherited code that uses this or we might work with a library making use of this.

避免的最好办法this失败的情况下是不使用this的。 但是,这并不总是一种选择。 我们可能有一个使用遗传代码this还是我们可能会在图书馆利用的工作, this

Object literals, constructor functions, and classes build objects over the prototype system. The this pseudo-parameter is used by the prototype system to give functions access to the other object properties.

对象文字,构造函数和class在原型系统上构建对象。 原型系统使用this伪参数来使函数可以访问其他对象属性。

Let’s take a look at some situations.

让我们看一些情况。

嵌套函数 (Nested Functions)

this loses context inside nested functions. :

this会丢失嵌套函数内部的上下文。 :

class Service {  constructor(){    this.numbers = [1,2,3];    this.token = "token";  }    doSomething(){    setTimeout(function doAnotherThing(){      this.numbers.forEach(function log(number){      //Cannot read property 'forEach' of undefined          console.log(number);          console.log(this.token);      });    }, 100);  }}let service = new Service();service.doSomething();

The doSomething() method has two nested functions: doAnotherThing() and log(). When service.doSomething() is called, this loses context in the nested functions.

doSomething()方法具有两个嵌套函数: doAnotherThing()log() 。 调用service.doSomething()this会丢失嵌套函数中的上下文。

bind() (bind())

One way to fix the problem is with bind(). :

解决问题的一种方法是使用bind() 。 :

doSomething(){   setTimeout(function doAnotherThing(){      this.numbers.forEach(function log(number){         console.log(number);         console.log(this.token);      }.bind(this));    }.bind(this), 100);  }

bind() creates a new version of the function that, when called, has the this value already set. Note that we need to use .bind(this) for every nested function.

bind()创建该函数的新版本,该函数在被调用时已经设置了this值。 请注意,我们需要为每个嵌套函数使用.bind(this)

function doAnotherThing(){ /*…*/}.bind(this) creates a version of doAnotherThing() that takes the this value from doSomething().

function doAnotherThing(){ /*…*/}.bind(this) . doAnotherThing() function doAnotherThing(){ /*…*/}.bind(this)创建doAnotherThing()的版本,该版本从doSomething()中获取this值。

那/自己 (that/self)

Another option is to declare and use a new variable that/self that stores the value of this from the doSomething() method.

另一种选择是声明并使用一个新的变量that/self ,该变量存储来自doSomething()方法的this变量的值。

:

doSomething(){   let that = this;   setTimeout(function doAnotherThing(){      that.numbers.forEach(function log(number){         console.log(number);         console.log(that.token);      });    }, 100);  }

We need to declare let that = this in all methods using this in nested functions.

我们需要在嵌套函数中使用this所有方法中声明let that = this

箭头功能 (Arrow function)

The arrow function offers another way to fix this issue. :

箭头功能提供了另一种解决此问题的方法。 :

doSomething(){   setTimeout(() => {     this.numbers.forEach(number => {         console.log(number);         console.log(this.token);      });    }, 100);  }

The arrow function does not have its own this. It takes the this value from its parent. The only problem with this fix is that we tend to lose the function name. The function name is important, as it improves readability by expressing the function intention.

箭头功能没有this 。 它从其父级获取this值。 此修复程序的唯一问题是,我们倾向于丢失函数名称。 函数名称很重要,因为它通过表达函数意图提高了可读性。

, with functions inferring the variable name:

,其函数可以推断变量名:

doSomething(){       let log = number => {     console.log(number);     console.log(this.token);   }       let doAnotherThing = () => {     this.numbers.forEach(log);   }       setTimeout(doAnotherThing, 100);}

Method as callback

回调方法

this loses context when the method is used as a callback.

当该方法用作回调时, this会丢失上下文。

:

class Service {  constructor(){    this.token = "token";   }    doSomething(){    console.log(this.token);//undefined  } }let service = new Service();

Now, let’s look at some situations where the method service.doSomething() is used as a callback.

现在,让我们看一下使用service.doSomething()方法作为回调的情况。

//callback on DOM event$("#btn").click(service.doSomething);//callback for timersetTimeout(service.doSomething, 0);//callback for custom functionrun(service.doSomething);function run(fn){  fn();}

In all previous situations this loses context.

在以前的所有情况下, this都是上下文。

bind() (bind())

We can use bind() to fix the problem. :

我们可以使用bind()解决问题。 :

//callback on DOM event$("#btn").click(service.doSomething.bind(service));//callback for timersetTimeout(service.doSomething.bind(service), 0);//callback for custom functionrun(service.doSomething.bind(service));

箭头功能 (Arrow function)

Another option is to create a new function that calls service.doSomething() .

另一种选择是创建一个调用service.doSomething()的新函数。

//callback on DOM event$("#btn").click(() => service.doSomething());//callback for timersetTimeout(() => service.doSomething(), 0);//callback for custom functionrun(() => service.doSomething());

React组件 (React Components)

In React components, this loses context when methods are used as callbacks for UI events.

在React组件中,当方法用作UI事件的回调时, this会丢失上下文。

:

class TodoAddForm extends React.Component {  constructor(){      super();      this.todos = [];  }    componentWillMount() {    this.setState({desc: ""});  }    add(){    let todo = {desc: this.state.desc};     //Cannot read property 'state' of undefined    this.todos.push(todo);  }    handleChange(event) {     //Cannot read property 'setState' of undefined     this.setState({desc: event.target.value});  }    render() {    return 
; }}ReactDOM.render(
, document.getElementById('root'));

A way to fix the problem is to create new functions in the constructor using bind(this).

解决该问题的一种方法是使用bind(this)在构造函数中创建新函数。

constructor(){   super();   this.todos = [];   this.handleChange = this.handleChange.bind(this);   this.add = this.add.bind(this);}

不使用“ this" (Not using “this")

No this, no problems with losing context. Objects can be created using factory functions. :

没有this ,没有上下文丢失的问题。 可以使用工厂功能创建对象。 :

function Service() {    let numbers = [1,2,3];  let token = "token";    function doSomething(){   setTimeout(function doAnotherThing(){     numbers.forEach(function log(number){        console.log(number);        console.log(token);      });    }, 100);  }    return Object.freeze({    doSomething  });}

This time the context is not lost when the method is used as a callback.

这次,将方法用作回调时上下文不会丢失。

let service = Service();service.doSomething();//callback on DOM event$("#btn").click(service.doSomething);//callback for timersetTimeout(service.doSomething, 0);//callback for custom functionrun(service.doSomething);

结论 (Conclusion)

this can lose context in different situations.

在不同情况下this可能会丢失上下文。

bind(), the that/self pattern, and arrow functions are tools at our disposal for solving the context problems.

bind() ,that / self模式和arrow函数是我们可以用来解决上下文问题的工具。

Factory functions give the option of creating objects without using this at all.

工厂函数提供了创建对象的选项,而根本不用this

was named one of the !

被称为

For more on applying functional programming techniques in React take a look at .

有关在React中应用函数式编程技术的更多信息,请查看

Learn functional React, in a project-based way, with .

通过 ,以基于项目的方式学习功能性React

翻译自:

this 上下文

转载地址:http://edwzd.baihongyu.com/

你可能感兴趣的文章
ES索引模板
查看>>
HDU2112 HDU Today 最短路+字符串哈希
查看>>
JPanel重绘
查看>>
图片放大器——wpf
查看>>
SCALA STEP BY STEP
查看>>
cocos2d-x学习笔记
查看>>
MySql中的变量定义
查看>>
Ruby数组的操作
查看>>
hdu1181暴搜
查看>>
解码字符串 Decode String
查看>>
json学习笔记
查看>>
工具:linux 性能监控工具-nmon
查看>>
fatal error C1853
查看>>
Ural 1001 - Reverse Root
查看>>
玩转webpack之webpack的entry output
查看>>
java 操作mongodb查询条件的常用设置
查看>>
黑马程序员_java基础笔记(02)...java语言基础组成
查看>>
关于缓存击穿
查看>>
对innodb 拷贝文件实现数据库的方式(转)
查看>>
python知识点 2014-07-09
查看>>