Подтвердить что ты не робот

Почему библиотеки Javascript имеют локальные ссылки на методы массива (push, slice и т.д.)?

Я читал код нескольких библиотек javascript. Я заметил, что AngularJS и Backbone.js сохраняют локальную ссылку на функции массива. например:

var push = [].push  // or array.push

в чем смысл делать это, когда массивы являются конструкцией языка и должны быть доступны глобально?

4b9b3361

Ответ 1

Поскольку функции прототипа Array могут применяться к не-массивам.

Например, push 'элементы в массив-подобный объект:

var o  = { length: 0 };
[].push.call(o, 'hi');
o; //Object {0: "hi", length: 1}

Другой распространенной практикой является slice 'включение объекта arguments в собственный массив:

(function() {
   return [].slice.call(arguments); //[1, 2]
}(1, 2));

Как вы можете видеть, сохранение ссылок на эти функции уменьшает накладные расходы, делает код меньшим и дружественным к минимуму.

По-моему, это в основном для удобства и удобочитаемости, поскольку многократное написание [].arrayMethod выглядит довольно неуклюжим. Повышения производительности и минимизации являются дополнительными.


Просматривая Angular источник, вот случаи, которые я нашел:

Backbone также slice объекты аргументов (События # триггер и Подчеркивая методы проксирования), он также использует slice в фрагмент коллекции #.

Ответ 2

Я думаю, что разработчики библиотек особенно заинтересованы в том, чтобы сделать их библиотеки устойчивыми к случайным вещам, которые могут происходить на странице. Если вы на ранней стадии получаете ссылку на правильный Array.prototype.push и используете закрытие, чтобы не допустить ее досягаемости от другого кода, о котором вы, как писатель библиотеки, не знаете, это уменьшило шансы (и значительно облегчает устранять неполадки, когда) что-то неожиданное происходит, если другой код на странице решает захватить этот встроенный метод, который Javascript очень разрешительный.

Рассмотрим:

function Library(){
 var push=[].push;
 var data=[]; 
 this.save1=function(x){push.call(data, x);}
 this.save2=function(x){data.push(x);}
 this.get=function(){console.log(data);}
}
var o=new Library();

//Random on-page code
Array.prototype.push=function(x){console.info("doSomethingCrazy!");}

//Lets use the library functionality!
o.save1(1);
o.save2(2);

Ответ 3

Одна из причин, отмеченная Дугласом Крокфордом в его лекции Метаморфоза Ajax, заключается в том, что разработчики библиотек JavaScript могут условно добавлять методы утилиты для например, что-то вроде string.split, так что он будет добавлен только к прототипу объекта, если он еще не определен стандартными библиотеками, предоставленными браузером.