今日学习啥呢。。 学习实现call吧; 反正没事干。。记录一波
##call
call怎么使用相信大家一定不陌生了。看一下概念:call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法。
举个栗子:
var foo = {
value: 1
};
function bar() {
console.log(this.value);
}
bar.call(foo); // 1
基本效果:
- call 改变了this的方向,指向了foo
- bar函数依旧正常执行了
我们如果实现它,大概思路是什么呢;我们先看下下面的代码;
var foo = {
value: 1,
bar: function() {
console.log(this.value)
}
};
foo.bar(); // 1
当我们调用call的时候。代码执行方式和上面是一样的。大概 思路就是foo对象本身添加了bar的属性。然后this就自动指向了foo对象; 但是总是给对象添加一个新的属性。是 有点不太合适。but我们可以用js的 delete属性删除掉; 看下主要逻辑:
- 1.将函数设为对象的属性
- 2.执行传入的函数
- 3.删除对象上的属性 ##模拟实现第一版
// 第一版
Function.prototype.call2 = function(context) {
// 首先要获取调用call的函数,用this可以获取
context.fn = this;
context.fn();
delete context.fn;
}
// 测试一下
var foo = {
value: 1
};
function bar() {
console.log(this.value);
}
bar.call2(foo); // 1
基本的功能实现了。但是我们通常函数还可以传入参数;比如下面的例子;
//测试代码
var foo = {
value: 1
};
function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value);
}
bar.call(foo, 'kevin', 18);
继续实现吧; ##代码第二版(函数支持传入参数) 对于参数实现思路。可以通过Arguments里面取出来。从第二位取到最后然后在放入参数;直接看代码吧
//第二版
Function.prototype.call2 = function(context) {
context.fn = this;
var args = [];
for(var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
eval('context.fn(' + args +')');
delete context.fn;
}