2013-08-10 2 views
2

Почему вы отрезаете массив так:JavaScript: зачем использовать прототип для вызова функции вместо вызова функции?

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

Вместо того, чтобы просто:

arr.slice(3); 

?

Каковы преимущества использования прототипа и вызова?

Спасибо!

+1

'arr' не может быть фактическим массивом. Это может быть параметр NodeList или параметр аргументов, поэтому метод среза недоступен. –

ответ

4

Основные преимущества реализованы, когда «arr» - это не массив, а что-то как массив; в частности, что-то с свойством «длина» и свойствами с цифровым ключом. Хорошими примерами являются объекты arguments и объекты NodeList из DOM. Эти вещи не будут иметь метод «среза», но они do имеют свойства с численным ключом и свойство «длина».

Трюк работает, потому что метод «среза» довольно прощает.

Если вы видите, что используется с тем, что, безусловно, массив уже, то вы смотрите на код, написанный на запутанном человека :)

О, и обратите внимание также, что укороченный является:

var foo = [].slice.call(arguments, 0); 

Вам не обязательно обращаться к прототипу напрямую, если вы этого не хотите; вы можете получить его из экземпляра массива так же легко. (Да, это стоит фиктивное распределение, но в этот день и возраст я не удивлюсь, если виртуальные машины оптимизируют это.)

+0

LOL. Благодаря! Что помогает. Поэтому, чтобы убедиться, что я понимаю: использование метода prototype/call позволяет использовать прототипы методов объектов на других объектах, которые не относятся к данному типу? –

+1

@MrA да - ** но **: он работает только в том случае, если он работает. Другими словами, этот трюк позволяет вам получить метод и вызвать его так, что 'this' - это какой-то объект, который вы выбрали. Будет ли этот метод работать? Ну, может быть, или нет. В этом случае это так. – Pointy

+0

Методы, которые работают с любым объектом, описаны в спецификации как общие методы. Вы можете напрямую скопировать ссылку на них, чтобы избежать создания собственной реализации. Например. 'List.prototype.add = Array.prototype.push'. или 'NodeList.prototype.each = Array.prototype.forEach' – Esailija

Смежные вопросы