理解并手写 apply() 函数
apply()函数,在功能上类似于call(),只是传递参数的格式有所不同。
dog.eat.call(cat, '鱼', '肉');
dog.eat.apply(cat, ['鱼', '肉']);
因此我们完全可以套用 '上一篇对call()的分析‘,得到下列代码。
Function.prototype.myApply = function(obj){ // 判断调用对象是否为函数 if(typeof this !== 'function'){ console.error('type error!') } // 判断绑定的对象 obj = obj || window; obj.fn = this; // 将执行结果保存并返回 let result = obj.fn(); // 删除context.fn属性 delete obj.fn; return result; }
最后考虑下方法中使用的参数(是传递过来的第二个参数),并且格式就是数组,可以之间使用。
Function.prototype.myApply = function(obj){ if(typeof this !== 'function'){ console.error('type error!') } obj = obj || window; obj.fn = this; // 之间使用传递过来的数组 let result = obj.fn(...arguments[1]); delete obj.fn; return result; }
当没有数组传递过来的时候,arguments[1]获取不到,会报错,因此要再加一层判断。
Function.prototype.myApply = function(obj){ if(typeof this !== 'function'){ console.error('type error!') } obj = obj || window; obj.fn = this; // 判断arguments[1]是否存在 if(arguments[1]){ result = obj.fn(...arguments[1]); }else{ result = obj.fn(); } delete obj.fn; return result; }
最后通过一个例子,来验证是否达到apply()的功能要求。
Function.prototype.myApply = function(obj){ if(typeof this !== 'function'){ console.error('type error!') } obj = obj || window; obj.fn = this; // 判断arguments[1]是否存在 if(arguments[1]){ result = obj.fn(...arguments[1]); }else{ result = obj.fn(); } delete obj.fn; return result; } let dog = { name: '狗', eat(food1, food2) { console.log(this.name + '爱吃' + food1 + food2); } } let cat = { name: '猫', } dog.eat.apply(cat, ['鱼', '肉']); // 猫爱吃鱼肉 dog.eat.myApply(cat, ['鱼', '肉']); // 猫爱吃鱼肉
另外两篇:'对apply()函数的分析' 和 '对bind()函数的分析' 。
本文来自博客园,作者:辉太狼`,转载请注明原文链接:https://www.cnblogs.com/HuiTaiLang1216/p/15979040.html