call、apply
一般用来改变 this
的指向。手动实现call,apply
核心就是改变函数内部的this指向。
实现call
实现思路:改变this指向,将目标函数作为对象的属性,利用arguments
数组对象获取传入的参数,删除该函数
var obj = {
value :1,
};
function func(){
console.log(this.value);
}
Function.prototype.myCall = function(context) {
context = context || window;
context.fn = this;//将函数作为对象的一个属性传入
context.fn();
delete context.fn;//删除该函数
}
下面来看一下有参数执行时的代码
和上面相比只是加入了arguments
处理了一下传入的参数
var obj = {
value :1,
};
function func2(name,age) {
console.log(this.value);
console.log(name);
console.log(age);
}
Function.prototype.myCall = function(context) {
context = context || window; //如果当前传入的值为空,指向window
context.fn = this;//将函数作为对象的一个属性传入
var args = [];//执行该函数
for (var i =1; i< arguments.length;i++ ){//获取传入的对象和参数值
args.push('arguments[' + i + ']') //注意,只能存入argument[1],argument[2]的形式,存入原始数据会报错
}
eval('context.fn(' + args +')');//拼凑执行该函数,同等于func("abc",23)
delete context.fn;//删除该函数
}
实现apply
和call
的不同点,就是argument
换成了arr
数组
var obj = {
value : 1
}
function func(name, age) {
console.log(this.value);
console.log(name);
console.log(age);
}
var arr = ["abc", 23]
func.apply(obj,arr);
Function.prototype.myApply = function (context, arr) {
context = context || window;
context.fn = this;
if (!arr) {
context.fn();
} else {
var args = [];
for (var i = 0; i<arr.length; i++) {//传入的数组进行处理
args.push('arr['+i+']');
}
eval('context.fn('+args+')');//等同于,func("abc",23)
}
delete context.fn;
}
1 条评论
对国际规则的解读具有前瞻性。