js实现call方法
用原生js实现call方法,实际上就是改变了this的指向。废话不多说直接看代码,代码中有注释。
//首先在函数Function的原型上定义mycall方法(有关原型的内容请自行了解)
Function.prototype.mycall = function (context) {
// 获取传送进来的对象context
var context = context || window
// 为context定义一个属性fn方法,赋值为this,改变this指向,当前this指向
// context,也就是指向传进来的对象或者下文的foo
context.fn = this
// 定义一个数组,获取传递进来的参数
var args = []
for (var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']')
// 重点:这块使用字符串拼接后并push进数组,
// 当前args = ['arguments[0]','arguments[1]']
// 重点来啦,这个时候肯定会有人问,为什么不直接push进数组呢?这是
// 因为如果直接push进数组,则args = ['jxd',18],而在当前的
// 上下文中并没有定义变量jxd和18,所以就会报错。
}
// 因此这儿使用eval函数来执行,因为当执行函数作为函数参数的时候
// eval会调用toString()方法,将['arguments[0]','arguments[1]']转为
// 'arguments[0]','arguments[1]'
eval('context.fn(' + args +')
// 执行完后删除fn属性,保持函数的清洁
delete context.fn
}
var foo = {
value:1
}
function bar(name,age) {
console.log(name + '今年' + age)
}
// 调用
bar.call2(foo,'jxd',18) // jxd今年18
es6语法实现
Function.prototype.call2 = function (context) {
var context = context || window
context.fn = this
var args = [...arguments].slice(1)
// es6扩展符可以把数组转换为参数添加到函数中执行
context.fn(...args)
delete context.fn
}
var foo = {
value:1
}
function bar(name,age) {
console.log(name + '今年' + age)
}
bar.call2(foo,'jxd',18) // jxd今年18