call()、bind()、apply()的区别

169 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

call()、bind()、apply()的区别

相信大家或多或少都了解过函数的这几个方法:call()bind()apply()

那么它们是干什么的呢?或者说有什么相同点,可以让它们相提并论呢?

相同点:

  • 都可以改变函数的上下文,也就是 this指向
  • 第一个参数都是 this 要指向的对象
  • 都可以利用后续参数传参

不同点:

call():

基本语法:

函数名.call(this 修改后的指向,arg1,arg2,arg3....)

// 第二个参数接收的是若干个参数的列表

应用场景:

适应于只有一个参数的函数

例如:

  • 伪数组排序
let list = { 0 : 1, 1 : 2, 2 : 3, length : 3 }

let arr = Array.prototype.slice.call(list)

console.log(arr)
  • 检测数组类型
Object.prototype.toString.call(true)

Object.prototype.toString.call('123')

apply():

基本语法:

函数名.apply(this 修改后的指向,数组或伪数组)

// 第二个参数接收的是一个参数数组

应用场景:

适应于有多个参数的函数:

例如:

  • 伪数组转真数组
let arr = []

arr.push.apply(are, obj)

console.log(arr)
  • 求数组最大值
let  arr  =  [10, 16, 24, 32, 5,15]

let max1 =  Math.max.apply(Math, arr)

console.log(arr)

bind():

基本语法:

函数名.bind(this 修改后的指向,arg1,arg2,arg3.....)

// 第二个参数接收的是参数列表

应用场景:

适应于回调函数 例如:

  • 定时器
var fn = function(){
	console.log(that.dd)
}

var obj = { dd:666, tt(){
	setTimeout(fn.bind(this),1000)
	}
 }

obj.tt()

需要注意的是,bind语法并 不会立即执行 函数,而是会返回一个改变指向后的新函数,常用于回调函数。当这个新函数被调用的时候,其 this 值为提供的值,其参数列表前几项,置为创建时指定的参数序列。