call实现:
apply 和 call 主要就是传参的区别。这里就不多说了,直接看代码。
//call 实现
Function.prototype.myCall = function(context) {
context.fn = this
var args = [...arguments].slice(1)
var result = context.fn(...args)
delete context.fn
return result
}
//调用
var obj = {
name: 'xiaoming'
}
function foo(sex, age) {
console.log(sex + ' ' + this.name + ' ' + age);
}
foo.myCall(obj, 'boy', '25');// boy xiaoming 25
实现原理:
其实就是把fn放在obj下面执行(后面得把obj.fn从obj上删除了,保持obj的孑然之身嘛!),context.fn = this,obj这个对象就不止name属性了吧,多了fn属性,就是函数foo。然后context.fn()执行的时候,由于fn是context也就是obj调用的,那么在foo内部执行的时候, this.name就会找到obj的name,变相达成了实现this指向的更改或者说是其他对象的劫持。
apply实现:
Function.prototype.myApply = function(context) {
var context = context || window
context.fn = this
var result;
// 需要判断是否存储第二个参数,如果存在,就将第二个参数展开
if(arguments[1]) {
result = context.fn(...arguments[1])
} else{
result = context.fn()
}
delete context.fn
return result
}