React 事件响应函数为什么要 bind

  这和 JavaScript 如何确定函数调用时 this 的值有关。JavaScript 确定 this 值的 5 种模式:

1. 函数调用模式

  如果不是以对象 "." 的方式调用,而是直接调用函数的话,那么 this 指向的是当前上下文的全局对象,比如在浏览器环境中的 window 对象。第 5 行 foo() 调用,this 指向的是当前调用上下文,所以 this.scope 指向全局变量 scope。第 17 行 func() 调用,虽然 func 指向的是对象 obj 的 foo 方法,但是在直接函数调用的时候, this 指向的依然是当前调用上下文,所以 this.scope 指向还是全局变量 scope,而不是对象 obj 的scope 属性。

var scope = "outer context"
function foo() {
  console.log("this points to " + this.scope);
}
//第 6 行调用 console 日志输出:this points to outer context
foo();

var obj = {
  scope: "obj",
  foo: function() {
    console.log("this points to " + this.scope);
  }
};

var func = obj.foo;
//第 17 行调用 console 日志输出:this points to outer context
func()
//第 19 行调用/ console 日志输出:this points to obj
obj.foo()

2. 方法调用模式

  上面代码中第 19 行 obj.foo() 是对象方法调用模式。对象方法调用模式中,方法中的 this 指向当前调用对象实例,所以上例第 19 行 console 日志输出:this points to obj

3 构造函数调用模式

  当用 new 关键字配合函数调用的时候,这个时候是构造函数模式,在构造函数中 this 指向 new 新创建的空对象。如果没有 new 关键字,直接调用构造函数,则构造函数就是普通函数,上下文(this)还是由调用的时候上下文决定。下例中第 9 行调用输出如第 7,8 行注释所示,this 指向新创建的空对象。下例中第 13 行调用输出如第 11,12 行注释所示,这种调用方式是函数调用方式,this 指向的是当前调用的上下文,函数调用后,上下文中的 scope 值变成了 ”obj“。

 1 var scope = "outer context"
 2 function Cat() {
 3   console.log("this points to " + this.scope);
 4   this.scope = "obj";
 5   console.log("this points to " + this.scope);
 6 }
 7 // console 日志输出:this points to undefined
 8 // console 日志输出:this points to obj
 9 var cat = new Cat();
10 
11 // console 日志输出:this points to outer context
12 // console 日志输出:this points to obj
13 Cat()
14
15 // console 日志输出:this points to obj
16 console.log("this points to " + this.scope);

4. apply 调用模式

  JavaScript 中,我们还可以用 call 和 apply 方式来调用函数。call 和 apply 调用函数的时候,可以传递一个上下文对象作为函数调用的第一个参数。call 和 apply 的区别是,call 调用的时候,从第二个参数开始,是原函数的参数;而调用 apply 的时候,原函数的参数以数组的形式,作为 apply 的第二个参数。

var scope = "outer context"
function foo(a,b) {
  console.log("this points to " + this.scope + ", a="+ a +", b="+ b);
}
var obj = {
  scope:"obj"
}
// console 日志输出:this points to obj, a=a, b=b
foo.call(obj, "a", "b");
// console 日志输出:this points to obj, a=a, b=b
foo.apply(obj, ["a", "b"]);

5. bind 调用模式

  JavaScript 中的 bind 方法是函数对象的属性,用来创建一个新函数,并将新函数的上下文(this)绑定到指定的对象上。下例中我们用 bind 函数创建一个新函数并赋值给 func,这个新函数的上下文 bind 到了对象 obj。

var scope = "outer context"
function foo() {
  console.log("this points to " + this.scope);
}
var obj = {
  scope:"obj"
}
var func = foo.bind(obj);
// console 日志输出:this points to obj
func();

6. 箭头函数调用模式

  箭头函数有个非常有用的特性,箭头函数的上下文是其定义的的地方决定的,而不是调用的时候决定的。下面用两个例子来说明一下。

var scope = "outer context"
var obj = {
  scope:"obj",
  foo:function(){
    return function() {
      console.log("this points to " + this.scope);
    }
  }
}
var func = obj.foo();
// console 日志输出:this points to outer context
func();

上例第 11 行是函数调用模式,所以 func 调用的时候,this 指向的是调用上下文,所以 this.scope 为 "outer context"。

 1 var scope = "outer context"
 2 var obj = {
 3   scope:"obj",
 4   foo:function(){
 5     return (ev) => console.log("this points to " + this.scope);
 6   }
 7 }
 8 var func = obj.foo();
 9 // console 日志输出:this points to obj
10 func();

  本例中,将 foo 方法返回的函数换成了箭头函数。第 10 行是函数调用模式,但是由于 func 现在指向的是一个箭头函数,而根据刚刚提到的箭头函数的特性”箭头函数的上下文是其定义的的地方决定的,而不是调用的时候决定的。“,所以 func 调用的时候,this 指向的箭头函数定义时的上下文,也就是 obj 对象,因此,函数中的 this.scope 为 "obj"。

7. React 事件响应函数需要 bind

  经过以上内容的描述,我们就能够理解为什么 React 事件响应函数需要 bind 了。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Lua 5.1 参考手册 by Roberto Ierusalimschy, Luiz Henrique de F...
    苏黎九歌阅读 14,181评论 0 38
  • 3.1 Counter 组件   React 是基于组件的声明式用户界面开发库。在 React 世界,一切都是组件...
    旺财sz阅读 5,333评论 0 0
  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 4,867评论 0 5
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,545评论 1 32
  • 1,缺啥补啥,怕啥练啥; 2,一切为我所用,所用为团队家; 3,我想变,我要变,我不得不变,我会变得越来越好。 今...
    房傲东阅读 125评论 0 0

友情链接更多精彩内容