call
一句话介绍call:
- call()方法在使用一个指定的this值和若干指定的参数值的前提下调用某个函数或方法。
举个例子:
var obj = {
value: 1
};
function parson() {
console.log(this.value);
}
bar.bind(foo); //1
- call改变了this指向,指向了parson
- parson函数执行了。
模拟步骤
- 讲函数设置为对象的属性
2.执行该函数
3.删除该函数
// 第一步
obj.fn = parson
//第二步
obj.fn();
// 第三步
detele obj.fn;
第一次尝试
Function.prototype.call2 = function (context) {
// 首先获取调用call的函数,用this可以获取;
context.fn = this;
// 传入参数确定怎么办?我们可以从arguments对象中取值,去除第二个到最后一个参数
let args = [];
for (var i = 1; i < arguments.length; i+) {
args.push('arguments[' + i + ']');
}
// 不定参的问题解决了,我们要吧这个参数放在要执行的函数的参数中去;
// 可以使用eval方法拼成一个函数
eval('context.fn(' + args + ')');
// context.fn(); // 执行函数
detele context.fn;
}
// 测试一下
var obj = {
value: 1
}
function parson() {
console.log(name);
console.log(age);
console.log(this.value);
}
parson.call2(obj, 'name', 15);
// name
// 15
// 1
ok 这样基本就实现了call的基本功能,不过还有两小点要注意一下。
1. this可以传参null,当为null的时候,指向window;
举个例子:
var value = 1;
function parson() {
console.log(this.value);
}
parson.call(null) // 1
2.函数是可以有返回值的
举个例子:
var obj = {
value: 1
}
function parson(name, age) {
return {
value: this.value,
name: name,
age: age
}
}
console.log(parson.call(obj, 'name', 15))
// Object {
// value: 1,
// name: 'name',
// age: 15
//}
好的,我们下改进后的代码
Function.prototype.call2 = function (context) {
context.fn = context || window; // 设置一个默认值
let args = [];
for (var i = 1; i < arguments.length; i+) {
args.push('arguments[' + i + ']');
}
var result = eval('context.fn(' + args + ')');
detele context.fn;
return result;
}
// 测试一下
var obj = {
value: 1
}
function parson() {
console.log(name);
console.log(age);
console.log(this.value);
}
parson.call2(obj, 'name', 15);
// name
// 15
// 1
到此,我们就完成了call的实现!
apply的模拟试下
apply的实现跟call类似,在这里直接给代码。
Function.prototype.apply2 = function (context, arr) {
context = context || window;
context.fn = this;
var result;
if (arr) {
var args = [];
for (var i = 1; i < arguments.length; i++) {
args.push('argsuments[' + i + ']');
}
result = eval('context.fn(' + args + ')');
} else {
result = context.fn()
}
detele = context.fn;
renturn result;
}
参考 [# JavaScript深入之call和apply的模拟实现
]
网友评论