1. call的模拟实现
call() 方法调用一个函数, 其具有一个指定的this值和分别地提供的参数(参数的列表)。返回值是你调用的方法的返回值,若该方法没有返回值,则返回undefined。语法:fun.call(thisArg, arg1, arg2, …);
1 | /** |
2. apply的模拟实现
apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数。返回值为调用有指定this值和参数的函数的结果。语法:func.apply(thisArg, [argsArray]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 /**
* 实现思路:apply() 与 call() 的区别在于传入参数的形式不同。
* apply() 接受两个参数,第一个参数指定了函数体内 this 对象的指向,
* 第二个参数为一个数组或类数组。apply() 方法把这个集合中的元素
* 作为参数传递给被调用的函数。以下基本与call相同
*/
Function.prototype.myApply = function(context, arr) {
context = context || global;
function getContextName(obj) {
var objName = Math.random();
if(obj.hasOwnProperty(objName)) {
getContextName(obj);
} else {
return objName;
}
}
var contexName = getContextName(context);
context.contexName = this;
if(!arr) {
var res = context.contextName;
} else {
var args = []; // 用来存放参数
for(var i = 0, len = arr.length; i < len; i++) {
args.push('arr[' + i + ']');
}
}
res = eval('context.contexName(' + args + ')');
context.contexName();
delete context.contexName;
return res;
}
// 测试
var val = 2;
var foo = {
val: 1,
};
function bar(name, age) {
console.log(this.val);
return {
val: this.val,
name: name,
age: age,
}
}
bar.myCall(null);
// node环境下,log undefined undefined
// 浏览器测试,log 2 2 { age: undefined, name: undefined, val: 2 }
console.log(bar.myCall(foo, ['zyy', 21]));
// 1 1 { val: 1, name: 'zyy', age: 21 }