JavaScript 为什么要通过原型 prototype 调用函数, 而不是直接调用?

时间:2022-09-29 15:46:01

现象

经常在网上或者阅读源码时看到下面的代码:

Array.prototype.slice.call(arr, 3);

而不是

arr.slice(3);

原因

这是为什么呢, 毕竟下面这种方法更短, 代码看起来也更清晰.
因为使用prototype.fn.call这种方式可以更好的复用代码, 下面这个例子:

var divs = document.getElementsByTagName('div');
var first_three_div = divs.slice(3) // TypeError: divs.slice is not a function
var first_three_div = Array.prototype.slice.call(divs, 3); // ok 

这里 divs 是一个 HTMLCollection 对象, 但不是一个 Array 对象, 因此直接调用 slice 会出现错误, 而使用 Array.prototype.slice.call 我们可以复用 Array 的方法实现 HTMLCollection 对象的 slice方法. 这是因为我们使用 call 调用原型方法, 使 this 指针指向 HTMLCollection 对象, 而且这个对象正好拥有 length 属性和通过数字下标获取元素的方法, 因此 slice 能够返回正确的结果.

总结

通过原型方法调用可以复用其他类型的方法, 比如非 Array 类型可以使用 slice 方法获得 slice 的功能.

参考

javascript-why-use-prototype-to-call-a-function-instead-of-just-calling-the-fun