ホームページ  >  記事  >  ウェブフロントエンド  >  JS コードを保守する 3 つの方法

JS コードを保守する 3 つの方法

php中世界最好的语言
php中世界最好的语言オリジナル
2018-06-04 10:45:381665ブラウズ

今回はJSコードをメンテナンスする3つの方法を紹介します。JSコードをメンテナンスする際の注意点は何ですか?実際のケースを見てみましょう。

メンテナンス。他の言語では、開発タスクを実行するために既存のオブジェクトをライブラリとして使用することを検討してください。 JS では、既存のオブジェクトを、何でもできる背景として扱うことができます。既存の JS オブジェクトをユーティリティ ライブラリのように扱う必要があります。

上書きメソッドはありません

新しいメソッドはありません

削除メソッドはありません

プロジェクトの唯一の開発者である場合、この種の変更は、それらを知っており、期待しているため、簡単に処理できます。チームで大規模なプロジェクトに取り組んでいる場合、このような変更は多くの混乱を引き起こし、多くの時間を無駄にする可能性があります。

メソッドをオーバーライドしない

JS での最悪の習慣は、所有していないオブジェクトのメソッドをオーバーライドすることです。JS で既存のメソッドをオーバーライドするのは非常に簡単です。神聖な document.getElementById() メソッドも例外ではなく、簡単にオーバーライドできます。おそらく、次のようなパターンを見たことがあるでしょう (このアプローチは「関数ハイジャック」とも呼ばれます):

// 不好的写法document._originalGetElementById = document.getElementById;document.getElementById = function (id) {  if (id === 'window') {    return window;
  } else {    return document._originalGetElementById(id);
  }
}

上の例では、ネイティブ メソッド document.getElementById() の「ポインタ」が document._originalGetElementById に保存されます。その後の使用。次に、 document.getElementById() が新しいメソッドによってオーバーライドされます。新しいメソッドは元のメソッドを呼び出すことがありますが、呼び出さない場合もあります。この「オーバーライドと信頼性の低下」パターンは、document.getElementById() が期待どおりに動作することもあれば、期待どおりに動作しないこともあるため、ネイティブ メソッドのオーバーライドと少なくとも同じくらい悪いです。 大規模なプロジェクトでは、このような問題が 1 つ発生すると、多くの時間と費用が無駄になる可能性があります。

新しいメソッドはありません

JS で既存のオブジェクトにメソッドを追加するのは非常に簡単です。関数を作成し、それを既存のオブジェクトのプロパティに割り当てて、メソッドにするだけです。このアプローチでは、あらゆる種類のオブジェクトを変更できます。

// 不好的写法 - 在
DOM对象
上增加了方法document.sayImAwesome = function () {
  alert("You're awesome.");
}// 不好的写法 - 在原生对象上增加了方法Array.prototype.reverseSort = function () {  return this.sort().reverse();
}// 不好的写法 - 在库对象上增加了方法YUI.doSomething = function () {  // 代码}

オブジェクトにメソッドを追加できないようにすることは、ほぼ不可能です (ES5 には、これを行うための 3 つの新しいメソッドがあり、後で紹介します)。自分が所有していないオブジェクトにメソッドを追加すると大きな問題が発生し、名前の競合が発生する可能性があります。現時点でオブジェクトにメソッドがないからといって、将来もメソッドがないわけではありません。 さらに悪いことに、ネイティブ メソッドが将来自分のメソッドと一貫性のない動作をするようになった場合、コード メンテナンスの悪夢に陥ることになります。

プロトタイプ JS クラス ライブラリの開発履歴から学ぶ必要があります。 Prototypeは、さまざまなJSオブジェクトを変更するという観点から非常に有名です。 DOM とネイティブ オブジェクトに非常に自由にメソッドを追加します。実際、ライブラリのコードのほとんどは、自分で オブジェクトを作成するのではなく、既存のオブジェクトを拡張するものとして定義されています。 Prototype の開発者は、このライブラリを JS を補完するものとみなしています。 1.6 より前のバージョンでは、Prototype は document.getElementsByClassName() メソッドを実装します。このメソッドは HTML5 で正式に定義されており、Prototype の使用法が標準化されているため、ご存知の方もいるかもしれません。

Prototype の document.getElementsByClassName() メソッドは、指定された CSS クラス名の要素を含む配列を返します。また、Prototype は、配列に対してメソッド Array.prototype.each() を追加します。このメソッドは、配列を反復処理して各要素に対して関数を実行します。これにより、開発者は次のようなコードを書くことができます:

document.getElementsByClassName('selected').each(doSomething);

HTML5 がこのメソッドを標準化し、ブラウザがネイティブに実装し始めるまで、コードは問題ありません。 Prototype チームは、ネイティブ document.getElementsByClassName() が登場することを知っていたため、次のような防御的なコードを追加しました:

if (!document.getElementsByClassName) {  document.getElementsByClassName = function (classes) {    // 非原生实现
  };
}

つまり、Prototype は、document.getElementsByClassName() が存在しない場合に定義するだけです。これで問題は解決したように見えますが、別の重要な事実があります。HTML5 document.getElementsByClassName() は配列を返さないため、 each() メソッドはまったく存在しません。ネイティブ DOM メソッドは、NodeList と呼ばれる特殊なコレクション タイプを使用します。 document.getElementsByClassName() は、他の DOM メソッド呼び出しと一致する NodeList を返します。

document.getElementsByClassName() メソッドがブラウザーでネイティブに実装されている場合、NodeList には each() メソッドがないため、ネイティブであっても Prototype によって追加された each() メソッドであっても、JS エラーがトリガーされます実行中。その結果、プロトタイプ ユーザーはクラス ライブラリ コードのアップグレードと自分自身のコードの変更の両方を行う必要があり、これはまさにメンテナンスの悪夢です。

从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中文网其它相关文章!

推荐阅读:

web开发中如何避免空比较

为什么web开发中需要避免使用全局变量

以上がJS コードを保守する 3 つの方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。