我们可以通过在Function的原型对象上添加方法来实现this指针上的bind,call,apply方法。需要注意的是,bind 方法会创建一个新的函数,并将指定的对象设置为新函数的上下文(即 this 的值),但并不立即调用该函数。而call和apply则是立即直接调用。
bind的实现
javascript
Function.prototype.mybind = function (context) {
var fn = this; // 保存原始函数的引用
var args = Array.prototype.slice.call(arguments, 1); // 获取除第一个参数外的其他参数
return function() {
var newArgs = args.concat(Array.prototype.slice.call(arguments)); // 将绑定时的参数和调用时的参数合并
return fn.apply(context, newArgs); // 使用 apply 方法调用原始函数并设置上下文
};
}
function greet(message) {
console.log(message + this.name);
}
var obj = { name: '张三' };
var boundFunc = greet.mybind(obj, '姓名:');
boundFunc(); // 输出:姓名:张三
在这个示例中,我们给 Function
的原型对象添加了一个 mybind
方法,以实现自定义的 bind
函数。定义了一个 greet
函数,然后使用 mybind
方法将其与 obj
上下文绑定,并传递 '姓名'
参数给 greet
函数。
call的实现
javascript
Function.prototype.mycall = function(context) {
context = context || window; // 如果未提供上下文,则默认为全局对象
context.ID = this; // 将当前函数设置为上下文对象的一个属性
// 获取传入的参数
var args = [];
for (var i = 1; i < arguments.length; i++) {
args.push('arguments[' + i + ']');
}
// 调用函数
var result = eval('context.ID(' + args + ')');
// 清除添加的属性
delete context.ID;
return result;
};
function greet(greeting) {
console.log(greeting + ':' + this.name);
}
var obj = { name: '张三' };
greet.mycall(obj, '姓名'); // 输出结果-- 姓名:张三
在这个示例中,我们给 Function
的原型对象添加了一个 mycall
方法,以实现自定义的 call
函数。定义了一个 greet
函数,然后使用 mycall
方法将其与 obj
上下文绑定,并传递 '姓名'
参数给 greet
函数。
apply的实现
ini
Function.prototype.myapply = function(context, argsArray) {
context = context || window; // 如果未提供上下文,则默认为全局对象
context.ID = this; // 将当前函数设置为上下文对象的一个属性
// 构建参数列表字符串
var args = [];
for (var i = 0; i < argsArray.length; i++) {
args.push('argsArray[' + i + ']');
}
// 调用函数
var result = eval('context.ID(' + args + ')');
// 清除添加的属性
delete context.ID;
return result;
};
function greet(greeting, punctuation) {
console.log(greeting + ': ' + this.name + punctuation);
}
var obj = { name: '张三' };
greet.myapply(obj, ['姓名',' 年龄:18']); // 输出结果为------姓名: 张三 年龄:18
在这个示例中,我们给 Function
的原型对象添加了一个 myapply
方法,以实现自定义的 apply
函数。定义了一个 greet
函数,然后使用 myapply
方法将其与 obj
上下文绑定,并传递 '姓名'
参数给 greet
函数。
总结
- 不传⼊第⼀个参数,那么默认为 window。
- 这些方法在调用时,传入的第一个参数为要绑定的上下文,后续参数为要传递给原始函数的参数。