call,bind,apply都是改变this指向的方法。
区别:
- call传递参数序列
- apply传递参数数组
- bind也是传递参数序列,返回一个函数,需要再次调用
call函数
Function.prototype.myCall = function (context, ...args) {
context = (context === null || context === undefined) ? window : Object(context)
args = args ? args : []
const key = Symbol()
context[key] = this
const result = context[key](...args)
delete context[key]
return result
}
function foo(params) {
console.log('foo函数执行', this, this.key)
}
function sum(m, n) {
console.log('sum函数执行', this)
console.log(m + n)
}
foo.call('abc')
foo.myCall({ key: 41 })
foo.myCall('abc')
foo.myCall(undefined)
sum.myCall('abc', 1, 20)
apply函数
Function.prototype.myApply = function (context, argArray) {
context = (context === null || context === undefined) ? window : Object(context)
const key = Symbol()
context[key] = this
let result
if (argArray === undefined || argArray === null) {
context[key]()
} else if (Array.isArray(argArray)) {
context[key](...argArray)
} else {
context[key](argArray)
}
delete context[key]
return result
}
function sum(m, n) {
console.log('sum执行', this)
console.log(m + n)
}
sum.myApply('abc', [10, 20])
sum.myApply('abc', 10)
bind函数
Function.prototype.myBind = function (context, ...args) {
context = (context === null || context === undefined) ? window : Object(context)
args = args ? args : []
const key = Symbol()
context[key] = this
return function (...argsNew) {
const result = context[key](...args, ...argsNew)
delete context[key]
return result
}
}
function sum(num1, num2, num3) {
console.log(this)
console.log(num1, num2, num3)
}
var result = sum.myBind('aaa', 10, 20,)
var a = result(40)
console.log(a)