现象
经常在网上或者阅读源码时看到下面的代码:
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