call实现
语法:
fun.call(thisArg, arg1, arg2, ...)
参数:
thisArg
- 在 fun 函数运行时指定的 this 值。if(thisArg == undefined|null) this = window,if(thisArg == number|boolean|string) this == new Number()|new Boolean()| new String()
arg1, arg2, ...
- 指定的参数列表。
Function.prototype.call2 = function (thisArg) {
if (thisArg === undefined || thisArg === null) {
thisArg = window;
} else {
switch (typeof thisArg) {
case 'number':
thisArg = new Number();
break;
case 'boolean':
thisArg = new Boolean();
break;
case 'string':
thisArg = new String();
break;
}
}
thisArg.fn = this;
let result;
if (arguments.length <= 1) {
result = thisArg.fn();
} else {
let args = [];
for (let i = 1; i < arguments.length; i++) {
args.push('arguments[' + i + ']');
}
result = eval(`thisArg.fn(${args})`)
}
delete thisArg.fn;
return result;
}
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call2(this, name, price);
this.category = 'food';
}
function Toy(name, price) {
Product.call2(this, name, price);
this.category = 'toy';
}
var cheese = new Food('feta', 5);
console.log('cheese: ', cheese);
var fun = new Toy('robot', 40);
console.log('fun: ', fun);
apply实现
语法:
func.apply(thisArg, [argsArray])
参数:
thisArg
- 可选的。在 func 函数运行时使用的 this 值。请注意,this可能不是该方法看到的实际值:如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动替换为指向全局对象,原始值会被包装。
argsArray
- 可选的。一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 func 函数。如果该参数的值为 null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。 浏览器兼容性 请参阅本文底部内容。
Function.prototype.apply2 = function (thisArg, argsArray) {
thisArg = thisArg || window;
thisArg.fn = this;
let result;
if (!argsArray) {
result = context.fn();
} else {
var tempArgs = [];
for (var i = 0, len = argsArray.length; i < len; i++) {
tempArgs.push('args[' + i + ']');
}
result = eval(`thisArg.fn(${tempArgs})`)
}
delete thisArg.fn;
return result;
}
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.apply2(this, [name, price]);
this.category = 'food';
}
function Toy(name, price) {
Product.apply2(this, [name, price]);
this.category = 'toy';
}
var cheese = new Food('feta', 5);
console.log('cheese: ', cheese);
var fun = new Toy('robot', 40);
console.log('fun: ', fun);
总结
实现难点:
- 需要考虑传入的thisArg的多种类型
- 将函数设置成thisArg的属性,来实现this的绑定,调用完成后需要delete该属性
- 使用eval来实现需要传参给该函数的情况
以上只是简单的实现,更详细的可以在这篇面试官问:能否模拟实现JS的call和apply方法查看。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。