简单介绍
共同点:
call apply bind 三个函数是Function对象中自带的方法,都是用来改变函数的this对象指向。
不同点:
- 第一个参数都是this要指向的对象,也就是想指定的上下文;
- call的第二个参数以逗号隔开,apply传入的是数组,bind第二个参数以逗号隔开;
- bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用;
手写call函数
Function.prototype.myCall = function(thisArg, ...args) {
声明一个独有的Symbol属性, 防止fn覆盖已有属性
const fn = Symbol('fn')
// 若没有传入this, 默认绑定window对象
thisArg = thisArg || window
// this指向调用call的对象,即我们要改变this指向的函数
thisArg[fn] = this
const result = thisArg[fn](...args) // 执行当前函数
delete thisArg[fn] // 删除我们声明的fn属性
return result // 返回函数执行结果
}
手写apply函数
Function.prototype.myApply = function(thisArg, args) {
// 声明一个独有的Symbol属性, 防止fn覆盖已有属性
const fn = Symbol('fn')
// 若没有传入this, 默认绑定window对象
thisArg = thisArg || window
// this指向调用call的对象,即我们要改变this指向的函数
thisArg[fn] = this
const result = thisArg[fn](...args) // 执行当前函数
delete thisArg[fn] // 删除我们声明的fn属性
return result // 返回函数执行结果
}
手写bind函数
ES6的简单写法
Function.prototype.myBind = function(thisArg, ...args){
const fn = this;
return function(...args1){
return fn.apply(thisArg,...args,...args1);
}
}
ES5+支持new
Function.prototype.myBind = function (thisArg, ...args) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
var self = this
var fbound = function () {
// 如果当前函数的this指向的是构造函数中的this 则判定为new 操作
self.apply(this instanceof self ? this : thisArg, args.concat(Array.prototype.slice.call(arguments)))
}
// 继承原型上的属性和方法
fbound.prototype = self.prototype;
return fbound;
}