Open KFCVme50-CrazyThursday opened 4 years ago
用例1:
var foo = {
value: 111
}
function fun() {
console.log(this.value)
}
fun() // undefined
fun.call(foo) // 111
call 主要做了一下事情:
针对以上事情,当调用 call 的时候,把 foo 对象改造成如下::
var foo = {
value: 111,
fun: function() {
console.log(this.value)
}
}
foo.fun()
这个时候给foo对象添加了一个属性,使用delete删除即可。 因此,call 的过程为一下几步:
以上例子就是:
// first
foo.fn = fun
// second
foo.fn()
// third
delete foo.fn
根据这个思路,call的模拟实现即是以下过程:
Function.prototype.call1 = function(ctx) {
// 获取调用call的函数,用this可以获取
ctx.fn = this
ctx.fn()
delete ctx.fn()
}
接上
还存在以下特殊点:
Function.prototype.call2 = function (ctx) {
var ctx = ctx || window;
ctx.fn = this;
var args = [];
for(var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
var result = eval('ctx.fn(' + args +')');
delete context.fn
return result;
}
// 这里使用es6语法的话会精简一点:
Function.prototype.call3 = function (ctx, ...args) {
var ctx = ctx || window;
ctx.fn = this;
var result = eval('ctx.fn(...args)');
delete context.fn
return result;
}
apply与call原理类似,主要传入参数形式不同。当使用es6展开运算符时候,两者基本一致。上面es6版的call3也即为apply的实现
mdn 中对 call 的描述是: call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。