2013-06-25 2 views
3

Я просто читал this answer regarding hashing in Javascript, и, хотя он был определенно быстрее, чем принятый ответ, для функциитребуется функция reduce.Зачем проверять прототип, а не экземпляр?

Проверка наличия функции reduce достаточно проста; но в то время как большинство проверок, которые я делаю (и видел), проверяют на прототипе, это только заставило меня задуматься: каковы последствия проверки самого экземпляра? Почему проверка прототипа кажется предпочтительной?

// i.e. 

if (!!Array.prototype.reduce) { } 
// vs 
if (!![].reduce) 

У экземпляра определенно должен быть экземпляр, так что это одно, но это так?

+2

'Array' может * технически * быть перезаписанным, но конструктор' [] 'не может – Ian

+2

@ Ian-if Array перезаписывается, у вас есть проблемы с большим количеством проблем ... ;-) – RobG

+0

в любом случае, вы можете опустить "!!" поскольку методы «if» равны true или undefined, что является ложным ... Если вы проверяете метод массива, у вас, вероятно, уже есть массив, поэтому вам не нужен пустой, чтобы нажать «if (myArr.reduce) ", и понюхание вашей точной переменной более точно для загрузки. – dandavis

ответ

3

Просто провел тест: http://jsperf.com/prototype-vs-instance-property-check

Array.prototype.reduce является 3x быстрее благодаря конкретизации пустого массива, но реально, нет абсолютно никакой разницы, так как эти проверки почти всегда проверяет разовый, а не в коде который работает все время.

Я лично уменьшил это до [].method в течение многих лет. Я делаю то же самое для таких вещей, как Array.prototype.slice.call(..) vs [].slice.call(...), и они называются гораздо чаще, чем один раз.

Обратите внимание, что это действует только на Array, так что вы действительно не экономить много.

2

Вторая версия предполагает бесполезное создание пустого массива. Зачем это делать, когда вы можете просто спросить сам прототип и не создавать какие-либо экземпляры?

+0

Я действительно упомянул об этом, но мне было просто интересно, все ли в этом дело. Не сказать, что накладные расходы ничтожны; Я признаю это * и * выполнил проверку прототипа даже по этой причине. –

+0

@RichardNeilIlagan Я думаю, что помимо инициализации пустого массива для вызова функции ([] .reduce) среда выполнения JS должна искать цепочку прототипов экземпляра объекта, чтобы ее найти. Где, как Array.prototype.reduce, указывает время выполнения именно там, где его можно найти. – HMR

+3

@ HMR - на самом деле поиск '' [[Prototype]] экземпляра экземпляра короче и поэтому * должен * быть быстрее, поскольку пустой массив имеет только одно свойство (* длина *) для проверки. Таким образом, поиск пойдет почти непосредственно на прототип. С методом чистого свойства идентификатор * Array * должен быть разрешен в цепочке областей видимости, прежде чем начинать искать * prototype * среди свойств Array (их два). Но использование экземпляра может быть не быстрее, поскольку определение идентификаторов в глобальной области видится очень быстро (почти так же, как если бы браузеры проверяли глобальность перед локальным объектом переменной). – RobG