call
Function.prototype.call=function(context){
//新建对象cxt保存需要this指向的对象,没有则指向window。严格模式会报错
let cxt=context || window
//创建一个属性,并赋值原型
cxt.fn=this
//获取传入的参数,call第一个为this指向,其他都是传入参数
let args=Array.from(arguments).slice(1)
//判断是否有参数传入
let res=args?cxt.fn(...args):cxt.fn()
//使用delete删除对象cxt.fn上的原型
delete cxt.fn
return res
}
apply
Function.prototype.apply=function(context){
let cxt=context || window
cxt.fn=this
//获取传入的参数,apply第一个为this指向,其他参数都是第二个参数以数组形式传入
let args=Array.from(arguments[1])
let res=args?cxt.fn(...args):cxt.fn()
delete cxt.fn
return res
}
call与apply相差不大,只是传参方式不同。
bind
bind(thisArg[, arg1[, arg2[, ...]]])
thisArg:调用绑定函数时作为this参数传递给目标函数的值。
arg1, arg2, ...:当目标函数被调用时,预先添加到绑定函数的参数列表中的参数。
bind则需要注意几点:
- bind传参方式与call相同
- bind改变this指向后需调用在执行,call与apply则是直接执行
- 如果使用new运算符构造绑定函数,则忽略该值。
- 返回一个原函数的拷贝,并拥有指定的this值和初始参数。
Function.prototype.bind=function(context){
if(typeof this !== 'function'){
throw new TypeError('...')
}
var args=Array.from(arguments).slice(1),
fToBind=this,
fNOP=function(){},
fBound=function(){
return fToBind.call(
// this instanceof fBound === true时,说明返回的fBound被当做new的构造函数调用
this instanceof fBound?this:context||window,
...args.concat(Array.from(arguments))
)
}
// 维护原型关系
if(this.prototype){
FNOP.prototype=this.prototype
}
//使fBound.prototype是fNOP的实例
//返回的fBound若作为new的构造函数,new生成的新对象作为this传入fBound,新对象的__proto__就是fNOP的实例
fBound.prototype=new FNOP()
return FBound
}
给个三连吧,哐哐哐,别下次,别下次。