Dieses Mal stelle ich Ihnen drei Methoden zur Pflege von JS-Code vor. Was sind die Vorsichtsmaßnahmen für die Pflege von JS-Code?
Wartung. Erwägen Sie in anderen Sprachen die Verwendung vorhandener Objekte als Bibliotheken, um Entwicklungsaufgaben auszuführen. In JS können wir vorhandene Objekte als Hintergrund behandeln, auf dem alles getan werden kann. Sie sollten vorhandene JS-Objekte wie eine Dienstprogrammbibliothek behandeln.
Methoden nicht überschreiben
Keine neuen Methoden hinzufügen
Methoden nicht löschen
Wenn Sie der einzige Entwickler im Projekt sind, weil Sie es verstehen Sie haben Recht. Sie haben Erwartungen und diese Art von Modifikationen sind einfach zu handhaben. Wenn man mit einem Team an einem großen Projekt arbeitet, können Änderungen wie diese viel Verwirrung stiften und viel Zeit verschwenden.
Methoden nicht überschreiben
In JS ist es die schlechteste Vorgehensweise überhaupt, eine Methode für ein Objekt zu überschreiben, das Ihnen nicht gehört. Es ist unglaublich einfach, eine vorhandene Methode in JS zu überschreiben. Sogar die heilige Methode document.getElementById() ist keine Ausnahme und kann leicht überschrieben werden. Möglicherweise haben Sie ein ähnliches Muster wie das folgende gesehen (dieser Ansatz wird auch „Funktionsentführung“ genannt):
// 不好的写法document._originalGetElementById = document.getElementById;document.getElementById = function (id) { if (id === 'window') { return window; } else { return document._originalGetElementById(id); } }
Im obigen Beispiel wird der „Zeiger“ einer nativen Methode document.getElementById() gespeichert document._originalGetElementById zur späteren Verwendung. Anschließend wird document.getElementById() durch eine neue Methode überschrieben. Die neue Methode ruft manchmal die ursprüngliche Methode auf, in einem Fall jedoch nicht. Dieses „Überschreiben plus zuverlässige Verschlechterung“-Muster ist mindestens so schlimm wie das Überschreiben einer nativen Methode und wahrscheinlich noch schlimmer, da document.getElementById() manchmal wie erwartet funktioniert und manchmal nicht. Bei einem großen Projekt kann ein solches Problem zu einer großen Zeit- und Geldverschwendung führen.
Keine neuen Methoden
Es ist sehr einfach, Methoden zu vorhandenen Objekten in JS hinzuzufügen. Erstellen Sie einfach eine Funktion und weisen Sie sie einer Eigenschaft eines vorhandenen Objekts zu, um daraus eine Methode zu machen. Mit diesem Ansatz können alle Arten von Objekten geändert werden.
// 不好的写法 - 在 DOM对象 上增加了方法document.sayImAwesome = function () { alert("You're awesome."); }// 不好的写法 - 在原生对象上增加了方法Array.prototype.reverseSort = function () { return this.sort().reverse(); }// 不好的写法 - 在库对象上增加了方法YUI.doSomething = function () { // 代码}
Es ist fast unmöglich, Sie daran zu hindern, einem Objekt Methoden hinzuzufügen (ES5 fügt hierfür drei neue Methoden hinzu, die später vorgestellt werden). Das Hinzufügen von Methoden zu Objekten, die Sie nicht besitzen, stellt ein großes Problem dar und kann zu Namenskonflikten führen. Nur weil ein Objekt im Moment keine Methode hat, heißt das nicht, dass es in Zukunft keine mehr haben wird. Was noch schlimmer ist: Wenn sich die native Methode in Zukunft nicht mehr mit Ihrer Methode verhält, geraten Sie in einen Albtraum bei der Codewartung.
Wir müssen aus der Entwicklungsgeschichte der Prototype JS-Klassenbibliothek lernen. Der Prototyp ist aus der Perspektive der Modifikation verschiedener JS-Objekte sehr bekannt. Es fügt dem DOM und nativen Objekten sehr frei Methoden hinzu. Tatsächlich ist der größte Teil des Bibliothekscodes so definiert, dass er vorhandene Objekte erweitert, anstatt selbst Objekte zu erstellen. Die Entwickler von Prototype betrachten die Bibliothek als Ergänzung zu JS. In Versionen vor 1.6 implementiert Prototype eine document.getElementsByClassName()-Methode. Vielleicht kennen Sie diese Methode, weil sie offiziell in HTML5 definiert ist und die Verwendung von Prototype standardisiert.
Die Methode document.getElementsByClassName() von Prototype gibt ein Array zurück, das Elemente mit dem angegebenen CSS-Klassennamen enthält. Prototype fügt außerdem eine Methode zum Array hinzu, Array.prototype.each(), die das Array durchläuft und für jedes Element eine Funktion ausführt. Dadurch können Entwickler Code schreiben wie:
document.getElementsByClassName('selected').each(doSomething);
Dieser Code funktioniert einwandfrei, bis HTML5 diese Methode standardisiert und Browser damit beginnen, sie nativ zu implementieren. Als das Prototype-Team wusste, dass natives document.getElementsByClassName() kommen würde, fügten sie einen Verteidigungscode wie diesen hinzu:
if (!document.getElementsByClassName) { document.getElementsByClassName = function (classes) { // 非原生实现 }; }
Prototype definiert also nur document.getElementsByClassName(), wenn es nicht existiert. Damit scheint das Problem gelöst zu sein, aber es gibt noch eine weitere wichtige Tatsache: HTML5 document.getElementsByClassName() gibt kein Array zurück, daher existiert die Methode every() überhaupt nicht. Die nativen DOM-Methoden verwenden einen speziellen Sammlungstyp namens NodeList. document.getElementsByClassName() gibt eine NodeList zurück, die mit anderen DOM-Methodenaufrufen übereinstimmt.
Wenn die Methode document.getElementsByClassName() nativ im Browser implementiert ist, wird dies der Fall sein, da NodeList keine every()-Methode hat, unabhängig davon, ob es sich um die native oder die von Prototype hinzugefügte every()-Methode handelt einen JS-Fehler auslösen. Das Endergebnis ist, dass Prototype-Benutzer sowohl den Code der Klassenbibliothek aktualisieren als auch ihren eigenen Code ändern müssen, was ein wahrer Wartungsalptraum ist.
从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中文网其它相关文章!
推荐阅读:
Das obige ist der detaillierte Inhalt vonDrei Möglichkeiten, JS-Code zu verwalten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!