2015-03-03 3 views
3

Что может быть целью следующей идиомы?Цель этой идиомы в JavaScript

Function.apply.call(fn, console, args); 

Я никогда не видел, чтобы применение называлось «раньше».

+0

[MDN apply()] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply) – epascarello

+0

- это 'Function' здесь заполнитель для действительной функции , или вы говорите о фактическом конструкторе '' Function' (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function)? –

+0

@epascarello Я думаю, что вопрос касается использования 'apply' _and_' call' вместе, а не того, что 'apply' является –

ответ

2

Это, конечно, не идиоматическое :-) Давайте посмотрим, что она делает:

  • Function.apply является Function.prototype.apply метод - Function constructor наследует его.
  • этот метод получает .called, с fn в качестве значения this, в console в качестве первого аргумента, и args в качестве второго.

Таким образом, это должно быть эквивалентно fn.apply(console, args), которая вызывает fn (вероятно, console метод) на console объекта с динамическим args списка.

Так почему же это сделано? Потому что Function.apply.call(fn, console, args) не совсем эквивалентен fn.apply(console, args)! Это только когда fn.apply === Function.apply, что может быть не так.
Маловероятно, что кто-то переопределил бы свойство .apply - и если бы он это сделал, это была его ошибка - но есть проблема реального мира: fn объектов, которые не наследуются от Function.prototype, даже если они могут быть вызваны. Такое может произойти при ошибках реализации объектов хоста; и наиболее известным примером является Internet Explorer's console object.

4

Для вызова функции нам нужны «функция», «это» и «аргументы».

Использование Function.apply или Function.call сами по себе позволяет указать «это» и «аргументы», но не функцию для вызова, потому что они используют свои собственные this как функции, так что нам нужен дополнительный слой, чтобы установить, что «это» значение.

Вы могли бы вместо того, чтобы сказать:

fn.apply(console, args); 

, но это не будет работать, если fn.apply были перезаписаны.