React事件处理绑定this和JS中的this学习

目录

一、事件处理绑定this

1. 构造函数中使用bind()方法

2. 使用实验性的 public class fields 语法

3.es6的箭头函数

4.Function.prototype.bind 

参考:

二、JS中的this

参考:


一、事件处理绑定this

在 JavaScript 中,class的方法默认不会绑定 this。在传入了 onTouchStart时,若忘记绑定 this.touchStart,当你调用touchStart的时候, this 的值为 undefined。即事件处理中,未绑定this,无法获取、使用

touchStart(){ 
    console.log('lyl123 this1 = ' + this);//undefined
    setTimeout(() => {
      console.log('lyl123 this2 = ' + this);//undefined
      //this.test();
    }, 1000);
}        

test(){
    console.log('lyl123 test');
}

<div onTouchStart={this.touchStart}/>

React事件处理函数绑定this:构造中使用bind方法,实现方法处用箭头函数、声明处用箭头函数、声明处用bind方法

1. 构造函数中使用bind()方法

constructor(props) {
    super(props);
    // 为了在回调中使用 `this`,这个绑定是必不可少的
    this.touchStart = this.touchStart.bind(this);//给touchStart重新赋值,改变this的指向
}

touchStart(){ 
    console.log('lyl123 this1 = ' + this);
}   

<div onTouchStart={this.touchStart}/>

2. 使用实验性的 public class fields 语法

//Create React App 默认启用此语法。

touchStart = ()=>{
    console.log('lyl123 this1 = ' + this);
}

<div onTouchStart={this.touchStart}/>

3.es6的箭头函数

class Comp extends React.Component {
  touchStart(){ 
    console.log('lyl123 this1 = ' + this);
  }  
  render() {
    // 此语法确保 `touchStart` 内的 `this` 已被绑定。
    return (<div onTouchStart={()=>{ this.touchStart(); }} /> );
  }
}

此语法问题在于每次渲染 Comp组件时都会创建不同的回调函数。如果该回调函数作为 prop 传入子组件时,这些组件可能会进行额外的重新渲染。我们通常建议在构造器中绑定或使用 class fields 语法来避免这类性能问题。

4.Function.prototype.bind 

touchStart(){ 
    console.log('lyl123 this1 = ' + this);
}   

<div onTouchStart={this.touchStart.bind(this)}/>

Function.prototype.bind和使用箭头函数是等价的,实际上每次组件渲染时都生成了新的回调函数。

方式3/4的使用场景:需要传递额外参数时使用。

在循环中,通常我们会为事件处理函数传递额外的参数。例如,若 id 是你要删除那一行的 ID,以下两种方式都可以向事件处理函数传递参数:

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

在这两种情况下,React 的事件对象 e 会被作为第二个参数传递。如果通过箭头函数的方式,事件对象必须显式的进行传递,而通过 bind 的方式,事件对象以及更多的参数将会被隐式的进行传递。

参考:

React官网事件处理

React事件绑定this的几种方法

Understanding JavaScript Bind ()

 

二、JS中的this

this 永远指向最后调用它的那个对象

虽然obj.foo和foo指向同一个函数,但是执行结果可能不一样。请看下面的例子。


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

var foo = obj.foo;
var bar = 2;

obj.foo() // 1
foo() // 2


this指的是函数运行时所在的环境。对于obj.foo()来说,foo运行在obj环境,所以this指向obj;对于foo()来说,foo运行在全局环境,所以this指向全局环境。所以,两者的运行结果不一样。


this的设计目的就是在函数体内部,指代函数当前的运行环境。
var f = function () {
  console.log(x);
};
var f = function () {
  console.log(this.x);
}
上面代码中,函数体里面的this.x就是指当前运行环境的x。

bind 是创建一个新的函数,我们必须要手动去调用
b.bind(a,1,2)()


箭头函数的 this 始终指向函数定义时的 this,而非执行时。
箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined
  // onTouchStart={this.touchStart}
  onTouchStart={()=>{
    // this.touchStart.bind(this);
    this.touchStart();
  }}

参考:

this、apply、call、bind

Javascript 的 this 用法

JavaScript 的 this 原理         

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值