2016-09-19 5 views
0

Je veux rendre certaines fonctions disponibles pour tous mes tableaux.Modifier Array.prototype dans node.js

Par exemple, je veux une fonction pour supprimer les doublons:

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

Mais je veux faire ce travail de fonction dans mon ensemble du projet node.js.

Cela fonctionnera-t-il si je le mets simplement dans server.js qui est exécuté quand je tape npm start?

Ce serait génial si cela fonctionne aussi sur le client. Est-il possible ou devrais-je considérer le serveur et le client strictement séparés les uns des autres?

Est-ce une mauvaise pratique d'étendre Array.prototype comme ça? Je pense juste qu'il semble stupide d'écrire le code plusieurs fois.

Une autre option pourrait être d'utiliser

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

mais array.uniq() semble mieux que uniquify(array).

+0

Peut-être mieux pour l'examen du code? – Neal

Répondre

0

Il est considéré comme "mauvaise pratique" pour manipuler le prototype de tableau.

I (personnellement) ne pense pas que ce soit si mal de le faire avec quelque chose qui a un nom très « unique », mais des noms uniques sont difficiles à trouver.

Il est préférable d'avoir des fonctions utilitaires que vous pouvez appeler et utiliser quand vous voulez.

+1

Il ne peut pas simplement être appelé "mauvaise pratique" sans raisonnement. En particulier si c'est son propre programme, il est logique qu'il/elle modélise un domaine qui convient à ses besoins. Si le code en question est conçu pour être distribué à d'autres personnes dans le cadre de leurs propres projets, alors oui, je dirais qu'il est inconsidéré (c.-à-d. «Mauvais») de manipuler des prototypes natifs. Voir la réponse de @ TJCrowder pour un raisonnement plus adapté. – naomik

+0

C'est comme si "l'Eval est le mal". Bien sûr, si vous ne comprenez pas «eval», vous risquez de l'utiliser à mauvais escient et d'accueillir des tas de problèmes. Mais cela ne signifie pas que son utilisation n'est pas justifiée dans certains scénarios distincts. – naomik

+0

Les réponses de Mine et TJs sont fondamentalement la même chose juste l'autre réponse a plus de mots. ;-) – Neal

3

Première: Si vous allez ajouter des propriétés à Array.prototype, ne le font pas les ajouter via une simple affectation. Cela crée des propriétés énumérables et le code qui repose sur des tableaux ne possédant aucune propriété énumérable par défaut est rompu.

donc utiliser defineProperty à la place:

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

Pour vos questions:

Est-ce que ça marche si je l'ai mis dans server.js qui est exécuté lorsque je tape npm start?

Je ne suis pas sûr de ce que server.js vous parlez, mais si vous parlez de la modification des fichiers qui sont intégrés dans certaines parties du nœud ou npm plutôt que des parties de votre projet, je vous recommande fortement pas le faire.

Ce serait génial si cela fonctionne aussi sur le client. Est-il possible ou devrais-je considérer le serveur et le client strictement séparés les uns des autres?

Ils sont complètement séparés. Si vous voulez le faire sur le client, vous devez inclure le script uniq sur le client.

Est-ce une mauvaise pratique d'étendre Array.prototype comme ceci? Je pense juste qu'il semble stupide d'écrire le code plusieurs fois.

Il y a deux camps de la pensée sur ce point:

  1. Oui, il est mauvais. Vous risquez de rencontrer des conflits de noms avec quelqu'un d'autre en ajoutant le leur, différent uniq. Combiner le code de plusieurs sources devient très, très commun, augmentant les chances de ces problèmes. Les futures versions de la langue peuvent ajouter uniq. Puisque le comité qui dirige le langage (TC-39) essaie de contourner les conflits potentiels, si votre bibliothèque côté client devenait populaire, cela rendrait leur travail plus difficile. (MooTools a, plus d'une fois.)

  2. Non, ce n'est pas mauvais, c'est ce que les prototypes sont pour. Les conflits de noms peuvent être gérés si et quand. TC-39 peut le localiser.

Vous devrez décider vous-même si vous souhaitez le faire.

+0

+ pour cette réponse cool. Par exemple si vous ajoutez quelque chose à l'objet.prototype 'comme' Object.prototype.compare = func ... 'il va casser jQuery et vous fait tirer vos cheveux :) encore ... cela ne devrait pas vous éviter de modifier les propriétés par défaut. Faites-le comme suggéré dans cette réponse. – Redu

1

Une autre option est d'étendre la classe de tableau afin que vous puissiez obtenir le meilleur des deux mondes ...

Vous pouvez ajouter toutes les méthodes que vous voulez à votre classe newArray étendu sans polluer l'espace de noms global. Dans la mesure où dans le navigateur, vous devrez faire la même chose, même si cela dépend de si vous passez de ES6 à ES5, vous limitant aux navigateurs ES6 ou si vous cherchez un moyen de faire les choses travailler dans ES5 aussi bien. L'utilisation d'une fonction d'usine pour renvoyer votre type newArray est une approche - en prenant soin de vous assurer que les méthodes que vous ajoutez ne sont pas itérables.

Il y a une discussion ici:

Extending Array with ES6 classes

+0

Bonne idée. Mais vous n'avez pas vraiment besoin de cours pour ça. [Array sous-classement] (https://www.quora.com/Quel-que-le-array-inheritance-problem-et-pourquoi-est-sur-son-hard-to-solve/answer/%C3% 96mer-Ka% C5% 9Fdarma? Srid = 01By) peut encore être fait avec ES6 ou même avec ES5 en utilisant 'Object.setPrototypeOf' ou' __proto__' – Redu

0

Pour ce genre de méthodes que vous souhaitez utiliser plusieurs fois dans votre application, vous pouvez créer un fichier comme:

appUtils. js

var appUtils = {}; 

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

// can add other methods as well 

et vous pouvez demander ce fichier chaque fois que vous voulez utiliser cette f onction. Si vous avez d'autres méthodes réutilisables, vous pouvez les ajouter comme ci-dessus.