Home Javascript - 关于 apply, call, bind, this
Post
Cancel

Javascript - 关于 apply, call, bind, this

关于 apply, call, bind, this

这个话题在网上的讨论有很多,本文仅为浅析及重点备注。

apply,call,bind 三者的主要作用是为了改变函数中使用的this的指向。

那么问题来了:

为什么要改变this 的指向呢?

这就谈论到了ES5了,在ES5中,this的指向,始终指向最后调用它的对象

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var name = "windowsName";
function tFun() {
    var name = "Cherry";
    console.log(this.name);          // windowsName
    console.log("inner:" + this);    // inner: Window
}
tFun();
console.log("outer:" + this)         // outer: Window

//tFun() 相当于是隐式调用 window.tFun() 所以最后调用的对象是 window。


 var name = "windowsName";
 var obj = {
        name: "Cherry",
        fn : function () {
            console.log(this.name);      // Cherry
        }
 }
 obj.fn();

// obj.fn() 为 对象obj 调用,所以log 的是 Cherry

以上为使用对象调用时的方式, 那么我们知道对象是可被赋值/调用的。

被赋值或调用时,会出现什么状况:

1
2
3
4
5
6
7
8
9
10
11
var name = "windowsName";
var obj = {
    name : null,
    // name: "Cherry",
    fn : function () {
        console.log(this.name);      // windowsName
    }
}

var another = obj.fn;
another();

当对象obj的函数fn赋值到another 时,尚未被 调用,another() 相当于 window.another(),所以this指向的最后调用它的对象应该是 window

怎样改变this的指向呢?

  • 使用ES6中的箭头函数
    • 箭头函数的 this 始终指向函数定义时的 this,而非执行时。
  • 临时变量赋值 _self = this
  • 使用apply、call、bind
  • new 一个对象

如何使用apply,call,bind?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var name = 'windowname';
var obj = {
    name : 'objname',
    objFunApply: function(){

     setTimeout(function(){
          console.log(this.name)
     }.apply(obj),100)
    },
    objFunCall: function(){
        setTimeout(function(){
          console.log(this.name)
        }.call(obj),100)
    },
    objFunBind: function(){
      setTimeout(function(){
        console.log(this.name)
      }.bind(obj),100)
   }
      
}
obj.objFunApply()
obj.objFunCall()
obj.objFunBind()

apply,call,bind的区别

apply的调用方式:

1
fun.apply(thisArg, [argsArray])
  • thisArg 为指定的this
  • argsArray 为参数数组

call 的调用方式:

1
fun.call(thisArg[, arg1[, arg2[, ...]]])
  • thisArg 为指定的this
  • arg1 , arg2,…. argn 为 若干个参数

bind 的调用方式:

  • 按照MDN的说明: bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。

如:

1
2
3
4
5
6
7
8
9
10
11
12
var name = "windowname";
var obj = {
  name: "objname",
  objFun: function(value1, value2) {
    console.log(value1, value2);
  }
};

var another = obj.objFun;
another.apply(obj, [1, 2]);
another.call(obj, 1, 2);
another.bind(obj,1,2)()
This post is licensed under CC BY 4.0 by the author.

Javascript - 关于 null, undefined, 0, [], true, false, void

Javascript - 关于 Cookie、Session、Localstorage

Trending Tags