# Call Apply Bind
4 min read
Table of Contents
call, apply 和 bind 都是 JavaScript 中用于函数绑定的方法。
Apply 和 Call
Function.prototype.apply 方法调用给定 this 值函数,并将参数作为数组或类数组。
语法:func.apply(thisArg, [argsArray])
Function.prototype.call 方法调用给定的 this 值函数,并分别地提供参数。
语法:func.call(thisArg, arg1, arg2, ...)
两者返回值:指定 this 和参数之后的函数调用结果。
Apply 和 Call 比较
Function.prototype.apply和Function.prototype.call的作用是一样的。- 第一个参数都是要调用函数的母对象,它是调用上下文,在函数体内通过 this 来获得对它的引用。
- 从第二参数,
apply接受的是一个参数数组,把它作为参数传给函数。call接受的是参数列表(不固定长度),然后全部作为参数传给函数。 - call 比 apply 的性能好。
关于 this,你可以调用现有的函数,然后分配给不同的对象。通过 apply 或 call 你可以继承别的对象的方法。
var array = ['a', 'b']var elements = [0, 1, 2]
// 等价于 array.push(elements),相当于 array 继承了 [].push 方法;[].push.apply(array, elements) // array: ['a', 'b', 0, 1, 2]var person = { intro: function (name, company) { console.log(`I am ${name}, use ${company}`) },}var another = {}person.intro.call(another, 'ABC', 'javascript') // I am ABC, use javascript// anthoer 本来没有 intro 方法,通过 call 继承了 person 的 intro 中的方法apply 可以传入类数组,所以经常与 arugments 参数一起使用。
call 的实现
Function.prototype._call = function (context, ...args) { // 判断调用者是否为函数,this 就是调用的函数 if (typeof this !== 'function') { throw new Error('need function') }
// 生成唯一值用于挂载,后续删除 const fnKey = Symbol()
if (!context) { context = window }
context[fnKey] = this const res = context[fnKey](...args) delete context[fnKey] return res}Bind
bind 创建一个新函数,该函数在被调用时将 this 指定到提供的值,并在调用新函数时提供其余的参数。 简单的说,就是将函数的 this 绑定到指定的对象中。
语法:let boundFunc = func.bind(thisArg[,arg1[,arg2[, ...]]])
返回值:指定了 this 和参数之后的一个函数副本。
this.x = 9;const module = { x: 81,}const getX = function() { return this.x;}const boundGetX = getX.bind(module);getX(); => 9boundGetX(); => 81个人觉得,apply,call 和 bind 一个很重要的区别就是返回结果,前两者是调用了函数,返回执行之后的结果。后者是返回一个新的函数。