2013-12-04 2 views
14

Глядя на эту tutorial я увидел следующий код предложение в одном из комментариев:Функция применяется с аргументами, используя срез

init:function(callback){ 
      var that =this ; 
      return $http.jsonp(this.url).success(
       function(data){ 
        that.availableGenres = that.getGenres(data); 
        that.results = that.getResults(data); 
        if(callback)callback.apply(null,[].slice.call(arguments)) 
       } 
      ) 
     } 

Но эта линия callback.apply(null,[].slice.call(arguments)) выглядит странно для меня.

Почему бы не просто: callback.apply(null, arguments)? Потому что мне не нравится, когда я не понимаю, о чем я играл с этим Fiddle, чтобы понять необходимость функции slice. Но это дает мне тот же результат, и я до сих пор его не понимаю.

Кто-нибудь знает, почему slice не требуется?

+0

apply() вероятно ожидает, что второй параметр будет иметь метод .pop(), однако аргументы не имеют этого метода, потому что он не является реальным массивом – roo2

+1

@Eru: Нет. Он ожидает только, что он имеет .length' собственности, ничего больше. – Bergi

ответ

28

Вы действительно не нуждаются в этом, проходя arguments к apply непосредственно в порядке.

Указывается, что разрешено в EcmaScript 3, а EcmaScript 5 позволяет даже массивные объекты не только массивы и объекты аргументов. Возможно, это было необходимо для обратной совместимости с еще более ранними или ошибочными реализациями JS. Кроме того, как вы видите из других ответов, некоторые люди не знают об этом факте и думают, что им нужно будет передавать фактические массивы - поэтому они не нужны осторожно.

+0

спасибо. в этом есть смысл. возможно, более ранние версии IE нуждаются в том, чтобы – letiagoalves

+0

@letiagoalves: Да, это то, что я и предполагал, но я не могу найти никаких доказательств в Интернете. – Bergi

+0

Я также не нашел никаких доказательств в Интернете. Но я подтвердил, что передача 'arguments' для' apply' работает хотя бы в IE9 (с использованием браузера в режиме live). Я запускал 'var fn = function() {return Array.prototype.slice.call (аргументы) .join ('---'); }; (function() {return fn.apply (null, arguments);}) (1, 'a', true, {}, [], function() {}, /. * /); 'в консоли и он возвратил '" 1 --- a --- true --- [object Object] ------ function() {} --- /. */"'. – L0LN1NJ4

2

ломтик необходим, потому что function.apply требует массив, arguments is not a real array, но может быть преобразован в один, используя срез.

Объект arguments не является массивом. Он похож на массив, но у нет никаких свойств Array, кроме длины. Например, у нет метода pop. Однако он может быть преобразован в реальном массиве:

var args = Array.prototype.slice.call(arguments); 

это один из самых уродливых частей JavaScript

+1

Почему нужен метод 'pop'? – Bergi

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