-
Notifications
You must be signed in to change notification settings - Fork 0
模拟实现call和apply方法 #14
Copy link
Copy link
Open
Labels
Description
call和apply的用法
call() 方法使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数。apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。
function foo(name, age) {
console.log(this.value);
console.log(name, age);
}
var obj = {
value: 1
}
foo.call(obj, 'bobo', 18)
foo.apply(obj, ['bobo', 18])call方法模拟实现思想
调用对象的方法this会指向当前的对象,比如
var obj = {
value: 1,
getValue: function() {
console.log(this.value);
}
}
obj.getValue() // 1模拟实现call()方法目的就是把this绑定一个对象中,再执行对象的方法。
步骤分为:
- 将函数设为对象的属性
- 执行该函数
- 删除该函数
Function.prototype.myCall = function (context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
// this 参数可以传 null,当为 null 的时候,视为指向 window
var context = context || 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;
}测试:
function foo(name) {
console.log(this.value);
console.log(name);
}
var value = 1;
var obj = {
value: 2
}
foo.myCall(obj, 'bobo'); // 2apply模拟实现
apply和call实现原理差不多,只是处理参数不一样:
Function.prototype.myApply = function (context, arr) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
var context = context || window;
context.fn = this;
var result;
if (!arr) {
result = context.fn();
} else {
var args = [];
for (var i = 0, len = arr.length; i < len; i++) {
args.push('arr[' + i + ']');
}
result = eval('context.fn(' + args + ')');
}
delete context.fn;
return result;
}测试:
function foo(name) {
console.log(this.value);
console.log(name); // bobo
}
var value = 1;
var obj = {
value: 2
}
foo.myApply(obj, ['bobo']); // 2ES6语法实现
@作者:yck
// call模拟实现
Function.prototype.myCall = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
const args = [...arguments].slice(1)
const result = context.fn(...args)
delete context.fn
return result
}
// apply模拟实现
Function.prototype.myApply = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
let result
// 处理参数和 call 有区别
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
delete context.fn
return result
}Reactions are currently unavailable