call
call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法。
var foo = {
value: 1
};
function bar() {
console.log(this.value);
}
bar.call(foo); // 1
call改变了this的指向,此时的this指向全局window
简单模拟实现
function foo() {
value : 1;
bar: function() {
console.log(this.value)
}
}
foo.bar()
// 第一版
Function.prototype.call2 = function(context) {
// 首先要获取调用call的函数,用this可以获取
context.fn = this; // 调用的时候才去讲this进行赋给上下文
context.fn();
delete context.fn;
}
// 测试一下
var foo = {
value: 1
};
function bar() {
console.log(this.value);
}
bar.call2(foo); // 1
call 函数还能给定参数执行函数
// 第二版
思路:从argument中去拿到参数的信息,然后传到调用的方法作用域中去
Function.prototype.call2 = function(context) {
// 首先要获取调用call的函数,用this可以获取
context.fn = this; // 调用的时候才去讲this进行赋给上下文
var arg = []
// 将所有的atguments中的值进行动态的遍历
for(let i = 1; i < arguments.length; i++) {
args.push('arguments['+ i +']')
}
eval('context.fn(' + args +')') // args 会自动调用 Array.toString() 这个方法。 进行拼接
context.fn();
delete context.fn;
}
var foo = {
value: 1
};
function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value);
}
bar.call2(foo, 'kevin', 18);
// kevin
// 18
// 1
// 第三版
Function.prototype.call2 = function (context) {
var context = context || window; // 当函数空调的时候,传入的值为undefined,此时需要指向window
context.fn = this;
var args = [];
for(var i = 1, len = arguments.length; i < len; i++) {
args.push('arguments[' + i + ']');
}
var result = eval('context.fn(' + args +')');
delete context.fn
return result; // 调用完的对象是能够进行返回的
}
// 测试一下
var value = 2;
var obj = {
value: 1
}
function bar(name, age) {
console.log(this.value);
return {
value: this.value,
name: name,
age: age
}
}
bar.call2(null); // 2
console.log(bar.call2(obj, 'kevin', 18));
// 1
// Object {
// value: 1,
// name: 'kevin',
// age: 18
// }
call函数的实现:
Function.prototype.apply = function(context, arr) {
var context = Object(context) || window;
context.fn = this;
var result;
if(!arr) {
result = context.fn();
} else {
var args = []
for(let i =0;i< arr.length; i++) {
args.push('arr['+ i +']')
}
result = eval('context.fn('+args+')')
}
delete context.fn();
return result;
}