Cette fois, je vais vous présenter trois méthodes de maintenance du code JS. Quelles sont les précautions pour maintenir le code JS. Voici des cas pratiques, jetons un coup d'oeil.
Entretien. Dans d'autres langages, envisagez d'utiliser des objets existants comme bibliothèques pour accomplir des tâches de développement. En JS, nous pouvons traiter les objets existants comme un arrière-plan sur lequel tout peut être fait. Vous devez traiter les objets JS existants comme une bibliothèque d'utilitaires.
Ne pas écraser les méthodes
Ne pas ajouter de nouvelles méthodes
Ne pas supprimer les méthodes
Lorsque vous êtes le seul développeur du projet, car vous comprenez eux, vous avez raison. Ils ont des attentes et ce genre de modifications est facile à gérer. Lorsque vous travaillez sur un grand projet en équipe, de tels changements peuvent provoquer beaucoup de confusion et faire perdre beaucoup de temps.
Ne pas remplacer les méthodes
En JS, la pire pratique consiste à remplacer une méthode sur un objet que vous ne possédez pas. Il est incroyablement facile de remplacer une méthode existante en JS. Même la méthode sacrée document.getElementById() ne fait pas exception et peut être facilement remplacée. Peut-être avez-vous vu un modèle similaire au suivant (cette approche est également appelée « détournement de fonction ») :
// 不好的写法document._originalGetElementById = document.getElementById;document.getElementById = function (id) { if (id === 'window') { return window; } else { return document._originalGetElementById(id); } }
Dans l'exemple ci-dessus, le « pointeur » d'une méthode native document.getElementById() est enregistré dans le document _originalGetElementById pour une utilisation ultérieure. Ensuite, document.getElementById() est remplacé par une nouvelle méthode. La nouvelle méthode appelle parfois la méthode d’origine, mais dans un cas, ce n’est pas le cas. Ce modèle « remplacement plus dégradation fiable » est au moins aussi mauvais que le remplacement d'une méthode native, et probablement pire, car document.getElementById() fonctionne parfois comme prévu et parfois non. Sur un projet de grande envergure, un tel problème peut entraîner une perte de temps et d’argent considérable.
Aucune nouvelle méthode
Il est très simple d'ajouter des méthodes à des objets existants dans JS. Créez simplement une fonction et affectez-la à une propriété d'un objet existant, ce qui en fait une méthode. Cette approche peut modifier tous types d'objets.
// 不好的写法 - 在 DOM对象 上增加了方法document.sayImAwesome = function () { alert("You're awesome."); }// 不好的写法 - 在原生对象上增加了方法Array.prototype.reverseSort = function () { return this.sort().reverse(); }// 不好的写法 - 在库对象上增加了方法YUI.doSomething = function () { // 代码}
Il est presque impossible de vous empêcher d'ajouter des méthodes à n'importe quel objet (ES5 ajoute trois nouvelles méthodes pour ce faire, qui seront présentées plus tard). L'ajout de méthodes à des objets que vous ne possédez pas est un gros problème et peut entraîner des conflits de noms. Ce n’est pas parce qu’un objet n’a pas de méthode pour le moment qu’il n’en aura pas dans le futur. Ce qui est pire, c'est que si la méthode native se comporte de manière incohérente avec votre méthode à l'avenir, vous serez piégé dans un cauchemar de maintenance du code.
Nous devons tirer les leçons de l'historique du développement de la bibliothèque de classes Prototype JS. Le prototype est très connu du point de vue de la modification de divers objets JS. Il ajoute très librement des méthodes au DOM et aux objets natifs. En fait, la plupart du code de la bibliothèque est défini comme étendant des objets existants plutôt que de créer des objets vous-même. Les développeurs de Prototype considèrent la bibliothèque comme un complément à JS. Dans les versions antérieures à 1.6, Prototype implémente une méthode document.getElementsByClassName(). Peut-être reconnaissez-vous cette méthode car elle est officiellement définie en HTML5 et standardise l'utilisation de Prototype.
La méthode document.getElementsByClassName() de Prototype renvoie un tableau contenant des éléments avec le nom de classe CSS spécifié. Prototype ajoute également une méthode sur le tableau, Array.prototype.each(), qui parcourt le tableau et exécute une fonction sur chaque élément. Cela permet aux développeurs d'écrire du code comme :
document.getElementsByClassName('selected').each(doSomething);
Ce code fonctionnera correctement jusqu'à ce que HTML5 standardise cette méthode et que les navigateurs commencent à l'implémenter de manière native. Lorsque l'équipe Prototype a su que document.getElementsByClassName() natif arrivait, elle a ajouté du code défensif, comme suit :
if (!document.getElementsByClassName) { document.getElementsByClassName = function (classes) { // 非原生实现 }; }
Ainsi, Prototype définit simplement document.getElementsByClassName() lorsqu'il n'existe pas. Il semble que le problème soit résolu, mais il y a un autre fait important : HTML5 document.getElementsByClassName() ne renvoie pas de tableau, donc la méthode each() n'existe pas du tout. Les méthodes natives du DOM utilisent un type de collection spécialisé appelé NodeList. document.getElementsByClassName() renvoie une NodeList pour correspondre à d'autres appels de méthode DOM.
Si la méthode document.getElementsByClassName() est implémentée nativement dans le navigateur, alors comme NodeList n'a pas de méthode each(), qu'il s'agisse de la méthode native ou de la méthode each() ajoutée par Prototype, elle le sera déclencher une erreur JS. Le résultat final est que les utilisateurs du prototype doivent à la fois mettre à niveau le code de la bibliothèque de classes et modifier leur propre code, ce qui est vraiment un cauchemar de maintenance.
从Prototype的错误中可以学到,你不可能精确预测JS将来会如何变化。标准已经进化了,它们经常会从诸如Prototype这样的库代码中获得一些线索来决定下一代标准的新功能。事实上,原生的Array.prototype.forEach()方法在ECMAScript5有定义,它与Prototype的each()方法行为非常类似。问题是你不知道官方的功能与原生会有什么样的不同,甚至是微小的区别也将导致很大的问题。
大多数JS库代码有一个插件机制,允许为代码库安全地新增一些功能。如果想修改,最佳最可维护的方式是创建一个插件。
不删除方法
删除JS方法和新增方法一样简单。当然,覆盖一个方法也是删除已存在的方法的一种方式。最简单的删除一个方法的方式就是给对应的名字赋值为null。
// 不好的写法 - 删除了DOM方法document.getElementById = null;
将一个方法设置为null,不管它以前是怎么定义的,现在它已经不能被调用到了。如果方法是在对象的实例上定义的(相对于对象的原型而言),也可以使用delete操作符来删除。
var person = { name: 'Nicholas'};delete person.name;console.log(person.name); // undefined
上例中,从person对象中删除了name属性。delete操作符只能对实例的属性和方法起作用。如果在prototype的属性或方法上使用delete是不起作用的。例如:
// 不影响delete document.getElementById;console.log(document.getElementById('myelement')); // 仍然能工作
因为document.getElementById()是原型上的一个方法,使用delete是无法删除的。但是,仍然可以用对其赋值为null的方式来阻止被调用。
无需赘述,删除一个已存在对象的方法是糟糕的实践。不仅有依赖那个方法的开发者存在,而且使用该方法的代码有可能已经存在了。删除一个在用的方法会导致运行时错误。如果你的团队不应该使用某个方法,将其标识为“废弃”,可以用文档或者用静态代码分析器。删除一个方法绝对应该是最后的选择。
反之,不删除你拥有对象的方法实际上是比较好的实践。从库代码或原生对象上删除方法是非常难的事情,因为第三方代码正依赖于这些功能。在很多案例中,库代码和浏览器都会将有bug或不完整的方法保留很长一段时间,因为删除它们以后会在数不胜数的网站上导致错误。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!