为什么我在扩展对象时需要JavaScript原型?

时间:2018-03-20 14:02:30

标签: javascript oop

很长一段时间我用JavaScript编写代码,使用jQuery,ReactJS和NodeJS服务器端(ExpressJS)。我学到了部分MDN和其他来源,但有一个问题我无法找到答案 为什么遵循代码需要prototype对象的属性?为什么我无法直接从forEach对象使用Array?我的意思是,就OOP而言,如果Array类扩展类包含forEach方法,我可以直接从Array实例化的对象调用它,我不需要,使用反射找到基类,实例化它并从基类调用该方法。

Array.prototype.forEach.call(document.querySelectorAll('.klasses'), function(el){
    el.addEventListener('click', someFunction);
});

从这里取得的例子:https://www.smashingmagazine.com/2014/01/understanding-javascript-function-prototype-bind/

3 个答案:

答案 0 :(得分:2)

您的代码:

Array.prototype.forEach.call(document.querySelectorAll('.klasses'), function(el){
    el.addEventListener('click', someFunction);
});

确实可以写成

[].forEach.call(document.querySelectorAll('.klasses'), function(el){
    el.addEventListener('click', someFunction);
});

通过Array原型对象只是一种访问任何数组实例可用函数的方法,而无需实际创建数组。使用一个或另一个主要是偏好问题,虽然第二种形式确实涉及创建数组对象,但性能影响很小。

答案 1 :(得分:1)

  

为什么我不能直接从Array对象中使用forEach?

Array对象是用于创建数组的构造函数。它没有自己的forEach属性。

您可以从Array实例访问forEach属性(您可以使用new Array创建,也可以使用[]创建更多,或访问{{1}这将被应用于Array的实例。

答案 2 :(得分:1)

querySelectorAll没有返回数组,而是返回NodeList(如数组对象)。 NodeList有一个名为.length的属性,用于指示其中元素的数量。

某些浏览器/引擎/后端技术不兼容,因为NodeList没有必要提供函数forEach

因此,另一种方法是使用Array原型将NodeList转换为数组:

Array.prototype.forEach.call(document.querySelectorAll('.klasses'), function(el){...})

或者,您可以使用将使用属性Array.from创建数组的函数.length

Array.from(document.querySelectorAll('.klasses'));

来自MDN docs

  

虽然NodeList不是数组,但可以使用forEach()对其进行迭代。一些较旧的浏览器尚未实现此方法。您也可以使用Array.from将其转换为数组。