Pourquoi l'immutabilité est-elle si importante (ou nécessaire) dans JavaScript?

je travaille actuellement sur les cadres React JS et React Native . Sur la route à mi-chemin, je suis tombé sur L'immutabilité ou la immuable-bibliothèque JS , lorsque je lisais sur le Flux de Facebook et l'implémentation de Redux.

la question est, pourquoi l'immuabilité est-elle si importante? Ce qui est faux dans la mutation des objets? N'est-ce pas faire des choses simples?

donnons un exemple, laissez-nous considérez un simple lecteur de nouvelles app avec l'écran d'ouverture étant une vue de liste des titres de nouvelles.

si je mets tableau d'objets avec une valeur initialement Je ne peux pas le manipuler. C'est ce que dit le principe de l'immuabilité, Non? (Corrigez-moi si je me trompe.) Mais, et si j'ai un nouvel objet News qui doit être mis à jour? Dans le cas habituel, j'aurais pu juste ajouter l'objet au tableau. Comment puis-je réaliser dans ce cas? Supprimer le magasin et le recréer? L'ajout d'un objet au tableau n'est-il pas moins coûteux?

PS: Si l'exemple n'est pas la bonne façon d'expliquer l'immutabilité, s'il vous plaît faites-moi savoir ce qui est le bon exemple pratique.

129
demandé sur JJJ 2015-12-20 23:00:55

10 réponses

j'ai récemment fait des recherches sur le même sujet. Je ferai de mon mieux pour répondre à vos questions et essayer de partager ce que j'ai appris jusqu'à présent.

la question est, pourquoi l'immuabilité est-elle si importante? Ce qui est mauvais dans la mutation des objets? N'est-ce pas faire des choses simples?

fondamentalement, cela se résume au fait que l'immutabilité augmente la prévisibilité, la performance (indirectement) et permet le suivi des mutations.

prévisibilité

Mutation cache le changement, qui crée des effets secondaires (inattendus), qui peuvent causer des bogues désagréables. Lorsque vous appliquez immutabilité, vous pouvez garder votre architecture d'application et modèle mental simple, ce qui rend plus facile de raisonner sur votre application.

Performance

même si ajouter des valeurs à un objet immuable signifie qu'un une nouvelle instance doit être créée là où les valeurs existantes doivent être copiées et de nouvelles valeurs doivent être ajoutées au nouvel objet qui coûte de la mémoire, les objets immuables peuvent faire usage du partage structurel pour réduire la mémoire au-dessus.

toutes les mises à jour renvoient de nouvelles valeurs, mais les structures internes sont partagées avec réduire drastiquement l'utilisation de la mémoire (et le fracas GC). Cela signifie que si vous ajoutez à un vecteur avec 1000 éléments, il ne crée pas réellement un nouveau vecteur 1001-éléments de long. Très probablement, à l'interne seulement quelques les petits objets sont alloués.

vous pouvez en savoir plus sur ce ici .

Suivi De Mutation

outre une utilisation de mémoire réduite, immutabilité vous permet d'optimiser votre application en faisant usage de référence - et l'égalité de valeur. Cela le rend vraiment facile de voir si quelque chose a changé. Par exemple, un état changement dans un composant de réaction. Vous pouvez utiliser shouldComponentUpdate pour vérifier si l'état est identique en comparant les objets d'état et empêcher le rendu inutile. Vous pouvez en savoir plus sur ce ici .

ressources supplémentaires:

si je mets dire un tableau d'objets avec une valeur initiale. Je ne peux pas de la manipuler. C'est ce que dit le principe de l'immuabilité, Non?(Correct moi si je me trompe). Mais, et si j'ai un nouvel objet de nouvelles qui doit être mis à jour? Dans le cas habituel, j'aurais pu juste ajouter l'objet tableau. Comment puis-je atteindre dans ce cas? Supprimer le magasin et le recréer? Ajouter un objet au tableau n'est-il pas moins opération coûteuse?

Oui c'est correct. Si vous êtes confus sur la façon de mettre en œuvre ce dans votre application, je vous recommande de regarder comment redux fait cela pour se familiariser avec les concepts de base, il m'a beaucoup aidé.

j'aime utiliser Redux comme exemple, car il embrasse l'immuabilité. Il a un seul arbre d'état immuable (appelé store ) où toutes les modifications d'état sont explicites par envoi d'actions qui sont traitées par un réducteur qui accepte l'état précédent avec lesdites actions (une à la fois) et renvoie l'état suivant de votre application. Vous pouvez lire plus au sujet de ses principes de base ici .

il y a un excellent cours redux sur egghead.io Dan Abramov , l'auteur de redux, explique ces principes comme suit (j'ai modifié le code un peu pour mieux correspondre au scénario):

import React from 'react';
import ReactDOM from 'react-dom';

// Reducer.
const news = (state=[], action) => {
  switch(action.type) {
    case 'ADD_NEWS_ITEM': {
      return [ ...state, action.newsItem ];
    }
    default: {
        return state;
    }
  }
};

// Store.
const createStore = (reducer) => {
  let state;
  let listeners = [];

  const subscribe = (listener) => {
    listeners.push(listener);

    return () => {
      listeners = listeners.filter(cb => cb !== listener);
    };
  };

  const getState = () => state;

  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach( cb => cb() );
  };

  dispatch({});

  return { subscribe, getState, dispatch };
};

// Initialize store with reducer.
const store = createStore(news);

// Component.
const News = React.createClass({
  onAddNewsItem() {
    const { newsTitle } = this.refs;

    store.dispatch({
      type: 'ADD_NEWS_ITEM',
      newsItem: { title: newsTitle.value }
    });
  },

  render() {
    const { news } = this.props;

    return (
      <div>
        <input ref="newsTitle" />
        <button onClick={ this.onAddNewsItem }>add</button>
        <ul>
          { news.map( ({ title }) => <li>{ title }</li>) }
        </ul>
      </div>
    );
  }
});

// Handler that will execute when the store dispatches.
const render = () => {
  ReactDOM.render(
    <News news={ store.getState() } />,
    document.getElementById('news')
  );
};

// Entry point.
store.subscribe(render);
render();

en outre, ces vidéos démontrent en détail comment atteindre l'immuabilité pour:

125
répondu danillouz 2018-02-27 23:01:20

allant à contre-courant de l'Immuabilité

brève réponse: L'immutabilité est plus une tendance de la mode qu'une nécessité en JavaScript. Il y a quelques cas étroits où il devient utile (React/Redux la plupart du temps), mais généralement pour les mauvaises raisons.

longue réponse: lire ci-dessous.

pourquoi l'immutabilité est-elle si importante(ou nécessaire) dans javascript?

Eh bien, je suis heureux que vous avez demandé!

il y a quelque temps un gars très talentueux appelé Dan Abramov a écrit une bibliothèque de gestion d'état javascript appelé Redux qui utilise des fonctions pures et immuabilité. Il a également fait quelques vidéos vraiment cool qui ont rendu l'idée très facile à comprendre (et à vendre).

le timing était parfait. La nouveauté de Angular s'estompait, et JavaScript world était prêt à fixer sur la dernière chose qui avait le bon degré de fraîcheur, et cette bibliothèque était non seulement innovant, mais parfaitement intégré avec React qui était colportée par un autre Silicon Valley powerhouse .

aussi triste que cela puisse paraître, les modes règnent dans le monde du JavaScript. Maintenant Abramov est salué comme un demi-dieu et tous les simples mortels doivent se soumettre à la Dao De L'immuabilité ... Si cela a du sens ou pas.

Qu'est-ce qui ne va pas dans la mutation des objets?

rien!

en fait, les programmeurs ont muté des objets pour er... tant qu'il y a des objets à muter. 50 ans du développement de l'application dans d'autres mots.

Et pourquoi compliquer les choses? Quand vous avez l'objet cat et qu'il meurt, avez-vous vraiment besoin un second cat pour suivre le changement? La plupart des gens diraient cat.isDead = true et en finiraient avec ça.

ne rend-il pas les choses simples?

Oui! .. Bien sûr, il n'!

spécialement en JavaScript, qui dans la pratique est le plus utile pour rendre une vue de certains États qui est maintenue ailleurs (comme dans une base de données).

et si je avez-vous un nouvel objet News qui doit être mis à jour? ... Comment puis-je atteindre dans ce cas? Supprimer le magasin et le recréer? L'ajout d'un objet au tableau n'est-il pas moins coûteux?

Eh bien, vous pouvez aller à l'approche traditionnelle et mettre à jour l'objet News , de sorte que votre représentation en mémoire de cet objet change (et la vue affichée à l'utilisateur, ou alors on l'espère)...

ou alternativement...

You peut essayer l'approche sexy FP/immutabilité et ajouter vos modifications à la News objet à un tableau de suivi de chaque changement historique de sorte que vous pouvez itérer à travers le tableau et de comprendre ce que la représentation d'état correcte devrait être (phew!).

j'essaie d'apprendre ce qui est juste ici. S'il vous plaît ne m'éclairer :)

les modes vont et viennent buddy. Il y a plusieurs façons de dépecer un chat.

je suis désolé que vous ayez à supporter la confusion d'un ensemble en constante évolution de paradigmes de programmation. Mais hey, BIENVENUE AU CLUB!!

maintenant quelques points importants à se rappeler en ce qui concerne L'immuabilité, et vous obtiendrez ces jeter à vous avec l'intensité fiévreuse que seule la naïveté peut rassembler.

1) immutabilité est génial pour éviter les conditions de course dans des environnements multi-filetés .

les environnements multi-threadés (comme C++, Java et C#) sont coupables de la pratique de verrouiller des objets lorsque plus d'un thread veut les changer. C'est mauvais pour la performance, mais mieux que l'alternative de la corruption des données. Et pourtant, ce n'est pas aussi bien que de tout rendre immuable (Loué soit le Seigneur Haskell!).

MAIS HÉLAS! En JavaScript vous utilisez toujours sur un seul thread . Même les travailleurs du web (chacun s'exécute dans un contexte séparé ). Donc, puisque vous ne pouvez pas avoir un thread related condition de course dans votre contexte d'exécution (toutes ces belles variables globales et fermetures), le principal point en faveur de L'immutabilité va par la fenêtre.

(ayant dit que, il est un avantage à utiliser des fonctions pures dans les travailleurs web, qui est que vous n'aurez aucune attente sur le fait de jouer avec des objets sur le thread principal.)

2) immutabilité peut (d'une manière ou d'une autre) éviter les conditions de course dans l'état de votre application.

et voici le vrai nœud du problème, la plupart des développeurs (React) vous diront que L'immutabilité et la FP peuvent en quelque sorte faire fonctionner cette magie qui permet à l'état de votre application de devenir prévisible.

bien sûr, cela ne signifie pas que vous pouvez éviter conditions de course dans la base de données , pour tirer celui-ci, vous devez coordonner tous les utilisateurs dans tous les navigateurs , et pour cela, vous avez besoin d'une technologie back-end push comme WebSockets (plus sur ce ci-dessous) qui diffusera des changements à tous ceux qui exécutent l'application.

cette revendication plutôt confuse signifie simplement que les valeurs les plus récentes attribuées à un objet d'état (défini par un utilisateur unique opérant au sein de son navigateur) deviennent prévisibles. Qui est vraiment aucun progrès du tout. Parce que vous auriez pu utiliser une simple vieille variable mutée pour suivre votre état et vous sauriez que vous avez affaire aux dernières informations chaque fois que vous y accédez, et cela fonctionnera avec tout sauf React/Redux.

pourquoi? Parce que React est spécial.. et l'état du composant est géré via une chaîne d'événements sur lesquels vous n'avez aucun contrôle et sur lesquels vous vous basez se souvenir de ne pas muter directement l'état . Cela a été manipulé étonnamment du point de vue des relations publiques, le battage médiatique a transformé une lacune en mode sexy. Fashion mis à part, je préférerais voir immutabilité pour ce qu'elle est, c'est à dire un outil pour combler un vide quand votre choix de cadre ne gère pas l'état intuitivement.

3) les conditions de course sont catégoriquement mauvaises.

Eh bien, ils pourraient l'être si vous utilisez React. Mais ils sont rares, si vous chercher un cadre différent.

D'ailleurs, vous normalement avoir beaucoup plus gros problèmes pour traiter... des problèmes comme l'enfer de la dépendance. Comme une base de code gonflée. Comme si ton CSS n'était pas chargé. Comme un processus de construction lent ou d'être collé à une fin monolithique qui rend itération presque impossible. Comme des dévots inexpérimentés qui ne comprennent pas ce qui se passe et qui font tout un bordel.

vous savez. Réalité. Mais bon, qui se soucie de qui?

4) L'immuabilité rend utilisation de types de référence pour réduire l'impact sur les performances du suivi de chaque changement d'état.

parce que sérieusement, si vous allez copier des trucs à chaque fois que votre état change, vous feriez mieux de vous assurer que vous êtes intelligent à ce sujet.

5) immutabilité vous permet de défaire les choses .

car er.. c'est la fonction Numéro un que votre chef de projet va demander, droit?

6) État immuable a beaucoup de potentiel frais en combinaison avec des WebSockets

Last but not least, l'accumulation de deltas d'État rend un cas assez convaincant en combinaison avec des WebSockets, ce qui permet une consommation facile de état comme un flux d'événements immuables ...

une fois que le penny tombe sur ce concept (l'état étant un flux de Evénements -- plutôt qu'un ensemble grossier de documents représentant la dernière vue), le monde immuable devient un endroit magique à habiter. Un pays de source de l'événement merveille et possibilité que transcende le temps lui-même . Et quand fait correctement cela peut certainement faire des applications en temps réel easi er pour accomplir, vous venez de diffuser le flux d'événements à tous les intéressés afin qu'ils puissent construire leur propre représentation de le présent et écrire leurs propres changements dans la commune de flux.

mais à un moment donné, vous vous réveillez et vous vous rendez compte que toute cette merveille et cette magie ne sont pas gratuites. Contrairement à vos collègues enthousiastes, vos intervenants (Oui, les gens qui vous paient) se soucient peu de la Mode et beaucoup de l'argent qu'ils paient pour construire un produit qu'ils peuvent vendre. Et la ligne de fond est que son plus difficile à écrire le code immuable et plus facile à le briser, plus il ya peu de point d'avoir un immuable front-end si vous n'avez pas de back-end pour la soutenir. Quand (et si!) vous avez finalement convaincu vos parties prenantes que vous devriez publier et consommer des événements via un push techology comme WebSockets, vous découvrez ce qu'est un douleur il est à l'échelle dans la production .


Maintenant, pour quelques conseils, si vous choisissez de l'accepter.

un choix d'écrire JavaScript en utilisant FP / immutabilité est aussi un choix pour rendre votre application code-base plus grande, plus complexe et plus difficile à gérer. Je plaiderais fortement pour limiter cette approche à vos réducteurs Redux.. sauf si tu sais ce que tu fais. En d'autres termes: juste Keep It Simple™. Vous serez mieux dans la plupart des cas. Et là où vous n'êtes pas, je me concentrerais sur Obtenir les avantages de données immuables circulant à travers votre (entière) application, plutôt que de construire un front-end purement fonctionnel et d'appeler la chose faite.

If you paid someone to draw you a horse, which one would you rather?

maintenant, si vous avez la chance de pouvoir faire des choix dans votre travail, alors essayez d'utiliser votre sagesse (ou non) et faites ce qui est juste par la personne qui vous paie . Vous pouvez baser cela sur votre expérience, sur votre instinct, ou ce qui se passe autour de vous (Certes, si tout le monde utilise React / Redux alors il y a un argument valable qu'il va être plus facile de trouver une ressource pour continuer votre travail).. Vous pouvez également essayer les approches reprendre le développement ou Hype Driven Development . Ils pourraient être plus votre genre de chose.

en bref, la chose à dire pour immuabilité est qu'il va vous rendre à la mode avec vos pairs, au moins jusqu'à ce que la prochaine folie vient autour, par lequel point vous serez heureux d'aller de l'avant.


j'ai ajouté ceci comme un article dans mon blog = > immutabilité en JavaScript: une vue Contrarienne . Hésitez pas à répondre si vous avez des sentiments forts vous souhaitez obtenir votre poitrine trop ;).

53
répondu Steven de Salas 2018-04-05 00:55:05

la question est, pourquoi l'immuabilité est-elle si importante? Ce qui est faux dans la mutation des objets? N'est-ce pas faire des choses simples?

en fait, le contraire est vrai: la mutabilité rend les choses plus compliquées, au moins à long terme. Oui, cela rend votre codage initial plus facile parce que vous pouvez juste changer les choses où vous voulez, mais quand votre programme va plus grand il devient un problème – si une valeur a changé, qu'est-ce qui l'a changé?

quand vous rendez tout immuable, cela signifie que les données ne peuvent plus être modifiées par surprise. Vous savez avec certitude que si vous passez une valeur dans une fonction, elle ne peut pas être changée dans cette fonction.

dit simplement: si vous utilisez des valeurs immuables, il est très facile de raisonner au sujet de votre code: tout le monde obtient une copie* unique de vos données, de sorte qu'il ne peut pas futz avec elle et briser d'autres parties de votre code. Imaginez combien cela rend plus facile de travailler dans un environnement multi-thread!

Note 1: Il y a un coût potentiel de performance à l'immutabilité selon ce que vous faites, mais des choses comme immuable.js optimiser du mieux qu'ils peuvent.

Note 2: dans le cas peu probable vous n'étiez pas sûr, immuable.js et ES6 const signifient des choses très différentes.

dans le cas habituel, j'aurais pu juste ajouter l'objet au tableau. Comment puis-je atteindre dans ce cas? Supprimer le magasin et le recréer? N'est pas d'ajouter un objet au tableau une opération moins chère? PS: Si l'exemple n'est pas la bonne façon d'expliquer l'immutabilité, veuillez me faire savoir quel est le bon exemple pratique.

Oui, votre exemple de news est parfaitement bon, et votre raisonnement est exactement le bon: vous ne pouvez pas simplement modifier votre liste existante, donc vous devez en créer une nouvelle:

var originalItems = Immutable.List.of(1, 2, 3);
var newItems = originalItems.push(4, 5, 6);
46
répondu TwoStraws 2015-12-20 20:33:44

bien que les autres réponses soient correctes, pour répondre à votre question sur un cas d'utilisation pratique (à partir des commentaires sur les autres réponses) permet de sortir de votre code de course pendant une minute et de regarder la réponse omniprésente juste sous votre nez: git . Que se passerait-il si chaque fois que vous poussez un commit vous overwrite les données dans le dépôt?

maintenant nous sommes dans l'un des problèmes que les collections immuables font face: la mémoire de la météorisation. Git est assez intelligent pour ne pas simplement faire de nouvelles copies de fichiers chaque fois que vous faites un changement, il garde simplement la trace des diffs .

bien que je ne sache pas grand chose sur le fonctionnement interne de git, Je ne peux que supposer qu'il utilise une stratégie similaire à celle des bibliothèques de référence: le partage structurel. Sous la hotte les bibliothèques utilisent tries ou d'autres arbres pour suivre seulement les noeuds qui sont différents.

cette stratégie est aussi raisonnablement performante pour les structures de données en mémoire car il y a bien connu les algorithmes de l'arbre-opération qui fonctionnent dans le temps logarithmique.

un autre cas d'utilisation: dire que vous voulez un bouton Annuler sur votre webapp. Avec des représentations immuables de vos données, la mise en œuvre de telles est relativement triviale. Mais si vous comptez sur la mutation, cela signifie que vous devez vous soucier de cacher l'état du monde et de faire des mises à jour atomiques.

en bref, il y a un prix à payer pour l'immuabilité dans la performance d'exécution et la courbe d'apprentissage. Mais n'importe quel programmeur expérimenté vous dira que le temps de débogage l'emporte sur le temps d'écriture de code d'un ordre de grandeur. Et le léger succès sur les performances d'exécution est probablement compensé par les bogues liés à l'état que vos utilisateurs n'ont pas à supporter.

29
répondu Jared Smith 2015-12-21 01:58:35

pourquoi L'immutabilité est-elle si importante(ou nécessaire) dans JavaScript?

immutabilité peut être suivi dans différents contextes, mais le plus important serait de le suivre par rapport à l'état de l'application et par rapport à L'interface utilisateur de l'application.

je considérerai le modèle Redux JavaScript comme une approche très tendance et moderne et parce que vous l'avez mentionné.

Pour l'INTERFACE utilisateur, nous avons besoin de le faire prévisible . Il sera prévisible si UI = f(application state) .

Applications (en JavaScript) ne modifiez pas l'état, via des actions mises en œuvre à l'aide de la réducteur de la fonction .

la fonction réducteur prend simplement l'action et l'ancien état et renvoie le nouvel état, en gardant l'ancien état intact.

new state  = r(current state, action)

enter image description here

L'avantage est: vous voyagez dans le temps les États puisque tous les objets d'état sont enregistrés, et vous pouvez rendre l'application dans n'importe quel État depuis UI = f(state)

donc vous pouvez annuler/refaire facilement.


se trouve à créer tous ces états peuvent encore être efficace de mémoire, une analogie avec Git est grande, et nous avons l'analogie similaire dans Linux OS avec des liens symboliques (basé sur les inodes).

6
répondu prosti 2017-02-02 11:08:59

la question est, pourquoi l'immuabilité est-elle si importante? Ce qui est faux dans la mutation des objets? N'est-ce pas faire des choses simples?

à propos de la mutabilité

D'un point de vue technique, il n'y a rien de mal à la mutabilité. Il est rapide, il réutilise la mémoire. Les développeurs y sont habitués depuis le début (comme je m'en souviens). Problème dans l'utilisation de la mutabilité et de troubles qui cela peut apporter.

si l'objet n'est pas partagé avec quoi que ce soit, par exemple existe dans la portée de la fonction et n'est pas exposé à l'extérieur, alors il est difficile de voir des avantages immuables. Vraiment, dans ce cas, il n'ya pas de sens à être immuable. Le sentiment d'immuabilité commence lorsque quelque chose est partagé.

la Mutabilité des maux de tête

Mutable structure partagée peut facilement créer de nombreux pièges. Un changement dans une partie du code avec l'accès à la référence a un impact sur d'autres parties avec la visibilité de cette référence. Un tel impact connecte toutes les parties ensemble, même quand ils ne devraient pas être au courant des différents modules. La Mutation dans une fonction peut planter la partie totalement différente de l'application. Une telle chose est un mauvais effet de côté.

ensuite souvent le problème avec la mutation est l'état corrompu. État corrompu peut se produire lorsque la procédure de mutation échoue au milieu, et certains champs ont été modifiés et certains pas.

de plus, avec la mutation, il est difficile de suivre le changement. Simple vérification des références ne montrera pas la différence, à savoir ce qui a changé profondément chèque doit être fait. En outre, pour surveiller le changement, un modèle observable doit être introduit.

enfin, la mutation est la raison du déficit de confiance. Comment vous pouvez être sûr qu'une structure a voulu de la valeur, si elle peut muter.

const car = { brand: 'Ferrari' };
doSomething(car);
console.log(car); // { brand: 'Fiat' }

comme le montre l'exemple ci-dessus, passant mutable la structure peut toujours finir par avoir une structure différente. Fonction doSomething est la mutation de l'attribut donné de l'extérieur. Pas de confiance pour le code, vous ne savez vraiment pas ce que vous avez et ce que vous aurez. Tous ces problèmes se produisent parce que: structures mutables représentent des indicateurs à la mémoire.

Immutabilité sur les valeurs

immutabilité signifie que le changement n'est pas fait sur le même objet,la même structure, mais le changement est représenté dans une nouvelle. Et c'est parce que la référence représente la valeur non seulement pointeur de mémoire. Chaque changement crée une nouvelle valeur et ne touche pas l'ancienne. De telles règles claires redonnent confiance et la prévisibilité du code. Les fonctions sont sûres à utiliser parce qu'au lieu de mutation, ils traitent de propres versions avec des valeurs propres.

L'utilisation de valeurs au lieu de conteneurs de mémoire donne la certitude que chaque objet représente une valeur spécifique immuable et il est sûr à utiliser il.

les structures immuables représentent les valeurs.

je plonge encore plus dans le sujet dans l'article moyen - https://medium.com/@macsikora/the-state-of-immutability-169d2cd11310

5
répondu Maciej Sikora 2018-01-01 23:08:25

un autre avantage de L'immutabilité en Javascript est qu'elle réduit le couplage temporel, ce qui présente des avantages substantiels pour la conception en général. Considérez l'interface d'un objet avec deux méthodes:

class Foo {

      baz() {
          // .... 
      }

      bar() {
          // ....
      }

}

const f = new Foo();

il se peut qu'un appel à baz() soit nécessaire pour obtenir l'objet dans un état valide pour qu'un appel à bar() fonctionne correctement. Mais comment savez-vous cela?

f.baz();
f.bar(); // this is ok

f.bar();
f.baz(); // this blows up

pour le comprendre vous devez scruter la classe interne parce qu'il n'est pas immédiatement évident d'examiner l'interface publique. Ce problème peut exploser dans une grande base de code avec beaucoup d'état et de classes mutables.

Si Foo est immuable, alors ce n'est plus un problème. Il est raisonnable de supposer que nous pouvons appeler baz ou bar dans n'importe quel ordre parce que l'état intérieur de la classe ne peut pas changer.

4
répondu ghostypants 2018-07-18 07:40:38

il était une fois un problème de synchronisation des données entre les threads. Ce problème était une grande douleur, il y avait 10+ solutions. Certains ont essayé de le résoudre radicalement. C'était un endroit où la programmation fonctionnelle est né. Il est juste comme le Marxisme. Je n'ai pas compris comment Dan Abramov a vendu cette idée à JS, parce que c'est un simple threaded. Il est un génie.

je peux donner un petit exemple. Il y a un attribut __attribute__((pure)) dans gcc. Les compilateurs tentent de résolvez si votre fonction est pure ou non si vous ne la décodez pas spécialement. Votre fonction peut être pur, même votre état est mutable. Immutabilité est juste un de plus de 100 façons de garantir que votre fonction sera pure. En fait 95% de vos fonctions seront purs.

vous ne devez pas utiliser de limitations (comme immutabilité) si vous n'avez pas une raison sérieuse. Si vous voulez "Défaire" de l'état, vous pouvez créer des opérations. Si vous voulez simplifier les communications que vous pouvez envoyer des événements avec des données immuables. C'est à vous.

j'écris ce message de la République post-marxiste. Je suis sûr que la radicalisation de toute idée est une mauvaise façon.

1
répondu puchu 2018-07-17 09:54:26

Une Prise Différente...

mon autre réponse aborde la question d'un point de vue très pratique, et je l'aime toujours. J'ai décidé d'ajouter ceci comme une autre réponse plutôt qu'un addendum à celle-ci parce que c'est un rant philosophique ennuyeux qui, espérons-le, répond aussi à la question, mais ne correspond pas vraiment à ma réponse existante.

TL; DR

même dans les petits projets immutabilité peut être utile, mais ne pas supposer que parce qu'elle existe, elle t'est destinée.

, Beaucoup plus longue réponse

NOTE: pour les besoins de cette réponse, j'utilise le mot "discipline" pour signifier l'abnégation pour quelque bénéfice.

c'est similaire dans la forme à une autre question: "devrais-je utiliser le dactylogramme? Pourquoi les types sont-ils si importants dans JavaScript?". Il a une réponse similaire aussi. Considérons le scénario suivant:

vous êtes le seul auteur et responsable D'une base de codes JavaScript/CSS/HTML d'environ 5000 lignes. Votre semi-technique patron lit quelque chose sur la Machine-comme-la-nouvelle-hotness et suggère que nous voulons déplacer, mais laisse la décision à vous. Donc vous lisez à ce sujet, jouez avec, etc.

alors maintenant que vous avez un choix à faire, passez-vous à la typographie?

dactylographié a quelques avantages convaincants: intellisense, Catch erreurs en avance, spécifier votre API en avance, facilité à réparer les choses lorsque le remaniement les casse, moins de tests. Typescript a également certains coûts: certaines idiomes JavaScript très naturel et correct peut être difficile à modéliser dans son système de type pas-particulièrement-puissant, annotations pousser la LoC, le temps et l'effort de réécrire codebase existante, étape supplémentaire dans le pipeline de construction, etc. Plus fondamentalement, il découpe un sous-ensemble de possibles programmes corrects JavaScript en échange pour la promesse que votre code est plus probable d'être correct. C'est arbitrairement restrictif. C'est tout le problème: vous imposez une certaine discipline qui vous limite (avec un peu de chance de vous tirer une balle dans le pied).

retour à la question, reformulée dans le contexte du paragraphe ci-dessus: is it worth it ?

Dans le scénario décrit, je maintiens que, si vous êtes très familier avec un petite à moyenne base de code JS, que le choix d'utiliser le typographie est plus esthétique que pratique. Et c'est bien , il n'y a rien mal avec l'esthétique, ils ne sont pas nécessairement convaincants.

Scénario B:

vous changez d'emploi et vous êtes maintenant programmeur en ligne chez Foo Corp. vous travaillez avec une équipe de 10 personnes sur une base de code Local 90000 (et en comptant) JavaScript / HTML/CSS avec un pipeline de construction assez compliqué impliquant babel, webpack, une suite de polyfills, réagir avec divers plugins, un système de gestion d'État, ~20 bibliothèques tierces, ~10 bibliothèques internes, éditeur de plugins comme un linter avec des règles pour le guide de style maison, etc. etc.

à l'époque où vous étiez un gars/une fille de 5k LoC, ça n'avait pas tellement d'importance. Même la documentation n'était pas que une grosse affaire, même revenir à une partie particulière de le code après 6 mois, vous pourriez le comprendre assez facilement. Mais maintenant la discipline n'est pas seulement agréable, mais nécessaire . Cette discipline n'implique peut-être pas de dactylographier, mais impliquera probablement une certaine forme d'analyse statique ainsi que toutes les autres formes de discipline de codage (documentation, guide de style, scripts de construction, test de régression, CI). La Discipline n'est plus un luxe , c'est une nécessité .

tout cela s'applique à GOTO en 1978: votre petit jeu de blackjack dinky en C pourrait utiliser GOTO s et logique spaghetti et il n'était tout simplement pas si grand une affaire de choisir-votre-propre-aventure votre chemin à travers elle, mais comme les programmes sont devenus plus grand et plus ambitieux, bien, indiscipliné l'utilisation de GOTO ne pouvait pas être soutenue. Et tout cela s'applique à l'immutabilité aujourd'hui.

tout comme les types statiques, si vous n'êtes pas en travaillant sur une grande base de codes avec une équipe d'ingénieurs qui la maintient et l'étend, le choix d'utiliser l'immutabilité est plus esthétique que pratique: ses avantages sont toujours là, mais ils ne compensent peut-être pas encore les coûts.

mais comme pour toutes les disciplines utiles, il arrive un moment où elle n'est plus optionnelle. Si je veux maintenir un poids santé, alors la discipline impliquant la crème glacée peut être facultative. Mais si je veux être un athlète de compétition, mon choix de manger ou non la crème glacée est subsumé par mon choix d'objectifs. Si vous voulez changer le monde avec le logiciel, l'immuabilité peut-être partie de ce dont vous avez besoin pour éviter qu'il s'effondre sous son propre poids.

0
répondu Jared Smith 2018-09-12 13:49:58

je pense que la raison principale pro immuable objets, est de garder l'état de l'objet valide.

supposons que nous ayons un objet appelé arr . Cet objet est valide lorsque tous les éléments sont la même lettre.

// this function will change the letter in all the array
function fillWithZ(arr) {
    for (var i = 0; i < arr.length; ++i) {
        if (i === 4) // rare condition
            return arr; // some error here

        arr[i] = "Z";
    }

    return arr;
}

console.log(fillWithZ(["A","A","A"])) // ok, valid state
console.log(fillWithZ(["A","A","A","A","A","A"])) // bad, invalid state

si arr devient un objet immuable, alors nous serons sûrs que arr est toujours dans un état valide.

-1
répondu bedorlan 2017-04-22 16:57:04