2016-09-19 2 views
0

Я хочу сделать некоторые функции доступными для всех моих массивов.Изменить Array.prototype в node.js

Например, я хочу, функция удаления дубликатов:

Array.prototype.uniq = function() { 
    return Array.from(new Set(this)); 
}; 

Но я хочу, чтобы сделать эту работу функции во всем моих node.js проекте.

Будет ли это работать, если я просто поставлю его в server.js, который запускается при вводе npm start?

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

Неплохая практика продлить Array.prototype вот так? Я просто думаю, что глупо писать код много раз.

Другие варианты могут быть использовать

function uniquify(arr) { 
    return Array.from(new Set(arr)); 
} 

но array.uniq() кажется лучше, чем uniquify(array).

+0

Возможно, лучше для обзора кода? – Neal

ответ

0

Это is считается «плохой практикой» для управления прототипом массива.

Я (лично) не думаю, что это так плохо делать с чем-то, что имеет очень «уникальное» имя, но тогда уникальные имена трудно найти.

Гораздо лучше иметь некоторые служебные функции, которые вы можете вызвать и использовать, когда захотите.

+1

Его нельзя просто назвать «плохой практикой» без рассуждений. В частности, если это ее/ее собственная программа, имеет смысл, что он/она моделирует домен, который соответствует его/ее потребностям. Если этот код разрабатывается для распространения другим пользователям для включения в их собственные проекты, то да, я бы сказал, что это неразумно (т. Е. «Плохо») манипулировать собственными прототипами. См. Ответ @ TJCrowder для более точных рассуждений. – naomik

+0

Это как «eval is evil» снова и снова. Конечно, если вы не понимаете 'eval', вы, вероятно, злоупотребляете им и приветствуете кучу проблем. Но это не означает, что его использование не оправдано в некоторых отдельных сценариях. – naomik

+0

Ответы Mine и TJs в основном то же самое, что и другой ответ, имеет больше слов. ;-) – Neal

3

Во-первых: Если вы собираетесь добавить свойства к Array.prototype, не добавить их с помощью простого присваивания. Это создает перечислимые свойства, и код, который полагается на массивы, не имеющие перечислимых свойств по умолчанию, будет ломаться.

Так используйте defineProperty вместо:

Object.defineProperty(Array.prototype, "uniq", { 
    value: function uniq() { 
     return Array.from(new Set(this)); 
    } 
}); 

на вопросы:

Будет ли это работать, если я просто положить его в server.js, которая запускается при вводе npm start?

Я не уверен, что server.js вы говорите, но если вы говорите об изменении файлов, встроенных в части узла или npm, а не части вашего проекта, я настоятельно рекомендую не так.

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

Они полностью разделены. Если вы хотите сделать это на клиенте, вам нужно будет добавить к клиенту добавление uniq.

Неплохая практика продлить Array.prototype вот так? Я просто думаю, что глупо писать код много раз.

Есть два лагеря мысли о том, что:

  1. Да, это плохо. Вероятно, вы столкнетесь с конфликтами именования с кем-то другим, добавляющим свои собственные, разные uniq. Объединение кода из нескольких источников становится очень, очень распространенным, увеличивая вероятность этих проблем. В будущих версиях языка можно добавить uniq. Поскольку комитет, управляющий языком (TC-39), пытается обойти потенциальные конфликты, если ваша библиотека на стороне клиента станет популярной, это сделает их работу более сложной. (MooTools имеет более одного раза.)

  2. Нет, это неплохо, для чего предназначены прототипы. Именование конфликтов можно обрабатывать, если и когда. TC-39 может разбить его.

Вам нужно будет принять собственное решение о том, делать это.

+0

+ для этого классного ответа. Например, если вы добавляете что-то в объект.prototype' like 'Object.prototype.compare = func ...' он сломает jQuery и заставит вас вытащить ваши волосы :), но ... это не должно мешать вам изменять свойства по умолчанию. Просто сделайте это, как было предложено в этом ответе. – Redu

1

Другой вариант заключается в расширении класса массива, так что вы можете получить лучшее из обоих миров ...

Вы можете добавить любые методы, которые вы хотите, чтобы ваш расширенный newArray класса, а не загрязнять глобальное пространство имен.

Насколько вы находитесь в браузере - вам нужно будет сделать то же самое, хотя это зависит от того, переписываете ли вы ES6 на ES5, ограничивая себя браузерами ES6 или если вы ищете способ сделать вещи работать в ES5.

Использование фабричной функции для возврата вашего типа newArray было бы одним подходом - быть внимательным, чтобы убедиться, что любые методы, которые вы добавляете, не являются итерируемыми.

Существует обсуждение этого здесь:

Extending Array with ES6 classes

+0

Хорошая идея. Но для этого вам не нужны классы. [Подкласс класса Array] (https://www.quora.com/What-is-the-array-inheritance-problem-and-why-is-it-so-hard-to-solve/answer/%C3% 96mer-Ka% C5% 9Fdarma? Srid = 01By) все еще можно сделать с ES6 или даже с ES5 с помощью 'Object.setPrototypeOf' или' __proto__' – Redu

0

Для такого рода методов, которые вы хотите использовать несколько раз в вашем приложении вы можете создать файл, например:

appUtils. JS

var appUtils = {}; 

appUtils.getUniqueArray = function() { 
    return Array.from(new Set(this)); 
}; 

// can add other methods as well 

, и вы можете требовать этого файла, куда вы хотите, чтобы использовать эту п соборование. Если у вас есть другие методы повторного использования, вы можете добавить их так же, как и выше.

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