js中call、apply和bind到底有什么区别?

介绍

在js中,每一个函数的原型都指向Function.prototype对象(js基于原型链的继承)。所以,每一个函数都会有apply,call,和bind方法,这些方法继承于Function。它们的做用是同样的,都是用来改变函数中this的指向。node

使用方法

apply的用法能够表示以下:A.apply(B, [x, y, z]);此方法能够改变函数A的this指向,使之指向函数B。第二个参数传的是一个函数参数列表的数组形式。es6

call的用法和apply差很少,就只有传参方式不同。相似于这样 :A.apply(B, x, y, z)能够把多个参数分开来传,而不是像apply同样,须要把全部参数放到一个数组里边传进来。数组

bind的传参方式和call同样,只不过它的不一样之处是,apply和call方法调用以后会当即执行,而bind方法调用以后会返回一个新的函数,它并不会当即执行,须要咱们手动执行。浏览器

举例

var name = "佚名";
var age = 20;
//global.name
//global.age

var p1 = {
    name: "张三",
    age: 12,
    func: function(){
        console.log(`姓名:${this.name},年龄:${this.age}`)
    }
}

var p2 = {
    name: "李四",
    age: 15
}

p1.func();  //姓名:张三,年龄:12
p1.func.call();  //姓名:佚名,年龄:20
p1.func.apply(p2);  //姓名:李四,年龄:15
p1.func.bind(p2)(); //姓名:李四,年龄:15复制代码

  1. 当直接调用p1.func方法时,this指向的是当前p1这个对象,所以name和age都是它自己对象的属性值。
  2. 当使用call方法,传入的第一个参数为空时,在浏览器环境下,this指向window;在node环境下,this指向global。读者可自行把name和age改成global.name和global.age验证一下。
  3. 使用apply方法时,把p2传进去,至关于把函数的this指向p2对象,所以,此时打印出来的属性都是p2对象的属性
  4. 使用bind方法时,会生成一个新的函数对象,所以须要手动执行一下这个函数(即在函数末尾加个括号执行)。

总结

例子讲完,call,apply和bind的区别就已经很清楚了。它们就是为了改变this的上下文而存在。所以,有时候你会看到这样的用法。为了避免改变this的指向,一般会在函数后边加上bind(this),以下app

function f(){}.bind(this)复制代码

这样的话,就不会出现莫名其妙的this指向问题了。明明我想在函数里边调用此函数所属对象的某个属性时,为何用this却访问不到呢。(写js的新手确定会遇到过这种问题)函数

其实,从es6开始,已经支持箭头函数了,我建议你们用箭头函数,就不会出现this指向的问题了。this

另外,使用call,apply还能够实现函数的继承。在es6的class没有出现以前,就须要借助它们来实现继承关系。spa

相关文章
相关标签/搜索