Array.prototype содержит много общих методов, которые можно применять к объектам, подобным массиву . [] является популярным ярлыком для доступа к этим методам. В этом посте рассматриваются плюсы и минусы использования этого ярлыка.
Обновление: Вдохновленный комментарием Кевина Робертса, я добавил третий способ доступа к общим методам и заключение.
Пояснения
Объекты, подобные массиву. Некоторые объекты в JavaScript являются
массив типа , они проиндексированы доступ и свойство длины как массивы, но ни один из методов массива. Подобные массиву объекты включают в себя специальные переменные аргументы (дающие индексированный доступ ко всем аргументам, переданным функции) и большинство результатов DOM. Отсутствие стандартных методов массива особенно прискорбно в ECMAScript 5, в котором есть такие полезности, как Array.prototype.forEach.
Универсальные методы. Некоторые методы являются общими . Хотя они непосредственно доступны экземплярам своего прототипа, они также могут быть заимствованы другими экземплярами. Чтобы заимствовать универсальный метод, вызывается один из следующих двух методов:
- Function.prototype.call (thisValue, [arg1], [arg2], …)
- Function.prototype.apply (thisValue, [arrayWithArguments])
Экземпляр заимствования является первым аргументом и становится его значением. Общие методы должны быть написаны так, чтобы они требовали, чтобы они имели только минимальный набор методов. Например, большинству универсальных методов массива это нужно только для обеспечения длины и индексированного доступа. Array.prototype.slice является универсальным и позволяет превратить любую часть объекта, подобного массиву, в массив.
Пример: общий вызов Array.prototype.map () для объекта аргументов в виде массива.
function prefixHello(prefix) { return Array.prototype.map.call(arguments, function(elem) { return "Hello "+elem; }); }
Взаимодействие:
> prefixHello("Jane", "John") [ 'Hello Jane', 'Hello John' ]
[] как ярлык. [] .foo часто используется как ярлык для Array.prototype.foo. То есть вы получаете доступ к свойству прототипа через экземпляр.
- Pro: более компактный.
- Con: На самом деле не описывает свои намерения. Вы не пытаетесь вызвать метод экземпляра, вы заимствуете функцию из прототипа.
- Против: Немного медленнее (см. Ниже).
Сроки нескольких способов доступа к универсальным методам
Я хотел посмотреть, насколько сильно пострадали плохие показатели, и быстро провел ненаучный тест. Тестовая структура:
var iterations = 100000000; var data = []; // empty so that slice() doesn’t have much to do (function () { var start = (new Date).getTime(); // loop var diff = (new Date).getTime() - start; console.log(diff); }());
Сроки прототипа доступа:
for(var i=0; i<iterations; i++) { Array.prototype.slice.call(data); }
Сроки ярлык:
for(var i=0; i<iterations; i++) { [].slice.call(data); }
Хранение прототипа в локальной переменной:
var arrayProto = Array.prototype; for(var i=0; i<iterations; i++) { arrayProto.slice.call(data); }
Результаты (iMac, Intel Core i5 с частотой 2,7 ГГц):
итерации | опытный образец | сокращенный | быстрый прототип | |
Node.js 0.4.8 | 100000000 | 5019ms | 5075ms | 4692ms |
Firefox 6 | 10000000 | 1592ms | 2237ms | 1522ms |
Rhino 1.7 выпуск 3 | 10000000 | 2318ms | 2687ms | 1878ms |
Вывод
Разница во времени не совсем потрясающая. Таким образом, если вы не работаете с критичным к производительности кодом, вы должны выбрать то, что, по вашему мнению,
лучше всего читается (в отличие от того, что легче всего писать).
С http://www.2ality.com/2011/08/array-prototype-performance.html