少し前に「Human High Quality Male」という動画が流行りました。見たことがある学生も多いと思います。そこで今日は、「人間品質のコード」とは何かを皆さんにお伝えしたいと思います。ハハ、冗談です。 実際、私がシェアしているのは、日常生活で私がまとめたちょっとしたコツです。皆さんにインスピレーションと助けをもたらすことができれば幸いです。 高品質な JavaScript コードを書くにはどうすればよいでしょうか?次の記事を一緒に勉強しましょう 1. 読みやすいコードまず、コードは自分自身やチームメンバーが読むために書かれており、適切な読み方は高品質なコードを書くための前提条件です。具体的な操作方法を4つまとめてご紹介します。 1. 統一コード形式時々このように書いたり、時々別の方法で書いたりしないでください。一貫性のある書き方を心がけてください。次に例を示します。 //悪い 関数foo(x,y) { 戻る { 合計: x + y }; } 関数バー(m, n){ ret = m*nとする ret を返します。 } //良い function foo(x, y) { // 適切なスペースで区切ります。通常、シンボルの前にはスペースは追加されませんが、シンボルの後にはスペースが追加されます。 return { sum: x + y, // 末尾のカンマは有効で、オブジェクトや配列への要素の追加や削除が簡単になります} // 終了セミコロンは省略できますが、リスクを回避する方法を知っておく必要があります} 関数バー(m, n) { ret = m * nとする リターン ret } コード形式を手動で決めるのは不便なので、prettier プラグイン (https://prettier.io/)などのツールを使用して形式を自動的に変換することができます。 2. マジックナンバーを削除する
//悪い タイムアウトを設定します(blastOff、86400000) document.onkeydown = 関数 (ev) { ev.keyCode === 13の場合{ // やること } } //良い 定数 1 日のミリ秒 = 86400000 定数 ENTER_KEY = 13 setTimeout(blastOff、1日あたりミリ秒) document.onkeydown = 関数 (ev) { ev.keyCode === ENTER_KEY の場合 { // やること } } もちろん、マジックストリングも上記と同様に扱われます。上記のコードでは定数に名前を付ける場合はアンダースコアを使用し、その他の変数や関数に名前を付ける場合はキャメルケースを使用することをお勧めします。 実は、 this の使用頻度を減らすことにも同じ原理が当てはまります。コードに //悪い クラスFoo { 関数foo(){ この数値 = 100 this.el.onclick = 関数 () { this.className = "アクティブ" } } } //良い クラスFoo { 関数foo(){ コンテキスト = this コンテキスト.番号 = 100 context.el.onclick = 関数 () { el = thisとする el.className = "アクティブ" } } } 3. 単一機能原則モジュール、クラス、関数のいずれを作成する場合でも、それぞれに単一の機能を持たせ、あまり多くの処理を行わないようにする必要があります。これにより、読みやすくなり、拡張も柔軟に行うことができます。 //悪い 関数コピー(obj, deep) { if (深い) { //ディープコピー} else { // 浅いコピー} } //良い 関数コピー(obj) { // 浅いコピー} 関数 deepCopy(obj) { // ディープコピー} 4. ネストレベル数を減らす 条件付きネスト、ループネスト、コールバックネストなどの多段階ネストはコードの可読性に非常に不利なので、ネストレベルはできる限り減らすべきです。 ネストされた条件の問題を解決するには、通常、 //悪い 関数foo(){ 結果を出す if (isDead) { 結果 = deadAmount() } それ以外 { if (isRet) { 結果 = retAmount() } それ以外 { 結果 = 通常の金額() } } 結果を返す } //良い 関数foo(){ if (isDead) { deadAmount() を返す } if (isRet) { retAmount() を返す } 通常の金額を返す() } ガード文に加えて、短絡演算や条件演算子などを使用して条件文を書き換えることもできます。 //悪い 関数foo(){ (正常かどうか) やること() } グレードを付ける if (isAdmin) { グレード = 1 } それ以外 { グレード = 0 } } //良い 関数foo(){ isOk && todo() // 短絡演算 let grade = isAdmin ? 1 : 0 // 条件演算子 } ネストされたコールバックの問題を解決するには、通常、「 //悪い fs = require("fs") とします。 関数init() { fs.mkdir(ルート、(エラー) => { fs.mkdir(path.join(root, "public", "stylesheets"), (err) => { fs.writeFile() 関数は、 path.join(ルート、"public"、"stylesheets"、"style.css")、 "", 関数 (エラー) {} ) }) }) } 初期化() //良い fs = require("fs").promises とします。 非同期関数init() { fs.mkdir(ルート) を待機します。 fs.mkdir(path.join(root, "public", "stylesheets")) を待ちます。 fs.writeFile(path.join(root, "public", "stylesheets", "style.css"), "") を待機します。 } 初期化() 上記で紹介した 4 つの提案に加えて、効果的な注釈、異なるタイプの比較の回避、ぎこちない文法の回避など、読書体験を改善できるポイントは他にもたくさんあります。 2. 高性能コードソフトウェア開発では、コードのパフォーマンスが製品のユーザーエクスペリエンスに直接影響するため、高品質のコードは高いパフォーマンスを備えている必要があります。具体的な操作方法を4つまとめてご紹介します。 ヒント: 1. 最適化アルゴリズム再帰は一般的なアルゴリズムです。以下は再帰を使用して実装された「階乗を求める」操作です。 //悪い 関数foo(n) { (n === 1)の場合{ 戻り値 1 } n * foo(n - 1) を返す } foo(100) // 平均時間: 0.47ms //良い 関数foo(n, 結果 = 1) { (n === 1)の場合{ 結果を返す } return foo(n - 1, n * result) // ここで末尾呼び出しの最適化} foo(100) // 平均時間: 0.09ms 「末尾呼び出し」は、スタック フレームを再利用できるメモリ管理最適化メカニズムです。つまり、外部関数の戻り値が内部関数の戻り値になります。 2. 組み込みメソッドを使用する多くの機能は、 次の例は、オブジェクトの属性と値の複合配列形式を取得する方法を示しています。 //悪い データ = { ユーザー名: "leo", 年齢: 20, 性別:「男性」、 } 結果 = [] for (let attr in data) { 結果.push([attr, data[attr]]) } console.log(結果) //良い データ = { ユーザー名: "leo", 年齢: 20, 性別:「男性」、 } 結果 = Object.entries(データ) console.log(結果) 3. スコープチェーンの検索を減らすスコープ チェーンは、スコープ ルールの実装です。スコープ チェーンの実装により、そのスコープ内で変数にアクセスしたり、そのスコープ内で関数を呼び出すことが可能になります。スコープ チェーンは、一方向にのみアクセスできるリンク リストです。このリンク リストの各ノードは、実行コンテキストの変数オブジェクト (コード実行時のアクティブ オブジェクト) です。一方向リンク リストの先頭 (アクセスできる最初のノード) は常に、現在呼び出されて実行されている関数の変数オブジェクト (アクティブ オブジェクト) であり、末尾は常にグローバル アクティブ オブジェクトです。 概念が複雑すぎる場合は、下の図をご覧ください。 スコープチェーンは 3 (head: bar) -> 2 (foo) -> 1 (tail: global) となっているため、変数を参照する際は先頭で取得を完了するようにすると、パフォーマンスを節約できます。具体的な比較は以下のとおりです。 //悪い 関数foo(){ $("li").click(function () { // グローバル検索を 1 回実行$("li").hide() // グローバル検索を再度実行$(this).show() }) } //良い 関数foo(){ let $li = $("li") // $liのスコープ検索レベルを下げます $li.click(function () { $li.非表示() $(これ).表示() }) } スコープ チェーンの検索を削減することに加えて、同じ原則がオブジェクト プロパティの検索を削減する場合にも適用されます。 //悪い 関数isNull(引数) { Object.prototype.toString.call(arg) === "[オブジェクト Null]" を返します } 関数isFunction(引数) { return Object.prototype.toString.call(arg) === "[オブジェクト関数]" } //良い toString = Object.prototype.toString とします。 関数isNull(引数) { return toString.call(arg) === "[オブジェクト Null]" } 関数isFunction(引数) { return toString.call(arg) === "[オブジェクト関数]" } 4. コードの重複を避けるプログラムを作成するときに、繰り返しコードが多くなることがありますが、繰り返し操作は避けるのが最善です。簡単な例を挙げて、ループを通じて条件を満たす最初の要素のインデックス位置を見つけてみましょう。 //悪い インデックスを0にする (i = 0, len = li.length; i < len; i++) の場合 { if (li[i].dataset.switch === "on") { インデックス = i } } //良い インデックスを0にする (i = 0, len = li.length; i < len; i++) の場合 { if (li[i].dataset.switch === "on") { インデックス = i break // 次のループは意味がなく、不要なコードを実行します} } 「フィボナッチ数列」を計算する別のケースを見てみましょう。 //悪い 関数foo(n) { (n < 3) の場合 { 戻り値 1 } foo(n - 1) + foo(n - 2) を返す } foo(40) // 平均時間: 1043ms //良い キャッシュを {} にします 関数foo(n) { (n < 3) の場合 { 戻り値 1 } if (!cache[n]) { キャッシュ[n] = foo(n - 1) + foo(n - 2) } キャッシュを返す[n] } foo(40) // 平均時間: 0.16ms ここでは、再帰実行の結果が配列にキャッシュされるため、次に繰り返されるコードはキャッシュ内のデータを直接読み取ることができ、パフォーマンスが大幅に向上します。 ×印の部分はキャッシュされ、計算は繰り返されません。 上記で紹介した 4 つの提案に加えて、DOM 操作の削減、処理の調整、イベントの委任など、コードのパフォーマンスを向上できるポイントは他にも多数あります。 3. 堅牢なコードいわゆる堅牢なコードとは、拡張可能、保守可能、テスト可能であるように記述されたコードです。具体的な操作方法を4つまとめてご紹介します。 1. 新しい構文を使用する多くの新しい構文は以前の構文のバグを補うことができ、コードをより堅牢で将来性のあるものにします。 //悪い 変数a = 1 isNaN(NaN) // 真 isNaN(未定義) // 真 //良い a = 1とする Number.isNaN(NaN) // 真 Number.isNaN(undefined) // false 新しい構文により、以前の操作が簡素化され、コード構造がより明確になります。 //悪い ユーザー = { 名前: "ジェームズ", 年齢: 36 } 関数foo(){ arg = 引数 名前 = ユーザー名 年齢 = user.age とします } //良い ユーザー = { 名前: "ジェームズ", 年齢: 36 } function foo(...arg) { // 残りパラメータ let { name, age } = user // 分割代入 } 2. いつでも拡張可能製品要件は常に新たな変更の影響を受けるため、ソフトウェアのスケーラビリティには高い要件が課せられます。そのため、堅牢なコードとはいつでも調整できるコードです。 //悪い 関数 foo(動物) { if (動物 === "犬" || 動物 === "猫") { // やること } } 関数バー(名前、年齢) {} バー("ジェームズ", 36) //良い 関数 foo(動物) { const animals = ["dog", "cat", "hamster", "turtle"] // 拡張可能な一致する値 if (animals.includes(animal)) { // やること } } function bar(options) {} // 任意のパラメータを拡張できる bar({ 性別:「男性」、 名前:「ジェームズ」、 年齢: 36歳 }) 3. 副作用を避ける関数が値を取得して結果を返す以外の動作を実行する場合、副作用が発生します。副作用は必ずしも有害ではありませんが、プロジェクト内で無制限に発生すると、コードエラーが発生する可能性が非常に高くなります。 グローバル変数や可変オブジェクトを変更せず、パラメータと //悪い フルーツ = 「アップルバナナ」 関数splitFruits() { フルーツ = fruit.split(" ") } 関数 addItemToCart(カート, アイテム) { cart.push({ アイテム、データ: Date.now() }) } //良い フルーツ = 「アップルバナナ」 関数splitFruits(果物) { 戻り値: fruit.split(" ") } 関数 addItemToCart(カート, アイテム) { [...cart, { item, data: Date.now() }] を返します } 4. 論理的な懸念を統合するプロジェクトが複雑すぎると、さまざまなロジックが混在することが多く、その後の拡張に非常に不利になり、コードの理解にも影響します。そのため、関連するロジックをまとめて抽出し、集中管理するようにしてください。 //悪い エクスポートデフォルト{ 名前: 'アプリ'、 データ(){ 戻る { 検索ホット: [], 検索候補: [], 検索履歴: [], }, マウント() { // ホットなtodo // ToDo 履歴 }, メソッド: { ハンドル検索サジェスト(){ // todo 提案 }, ハンドル検索履歴(){ // ToDo 履歴 } } } } //良い エクスポートデフォルト{ 名前:「アプリ」、 設定() { {searchHot} = useSearchHot() とします {searchSuggest、handleSearchSuggest} = useSearchSuggest() とします。 {searchHistory、handleSearchHistory} = useSearchHistory() とします。 戻る { 検索ホット、 検索提案、 検索履歴、 ハンドル検索提案、 ハンドル検索履歴、 } } } 関数useSearchHot() { // ホットなtodo } 関数useSearchSuggest() { // todo 提案 } 関数useSearchHistory() { // ToDo 履歴 } 上記で紹介した 4 つの提案に加えて、例外処理、単体テスト、JS の代わりに TS を使用するなど、コードの堅牢性を向上させるポイントは他にも多数あります。 最後に、高品質な 高品質な JavaScript コードの書き方に関するこの記事はこれで終わりです。高品質な JavaScript コードの書き方に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。皆様の今後の 123WORDPRESS.COM へのご支援をお待ちしております。 以下もご興味があるかもしれません:
|
<<: Docker で Jenkins サービスを構築する例
>>: MySQL 5.7.31 64 ビット無料インストール版チュートリアル図
フロントエンドのデザイン案では、「X」や「>」の形をした閉じるボタンや、他の 3 方向の白抜き...
<br />これは私がずっと前に集めた記事です。皆さんの参考のために共有したいと思います...
Docker コンテナに入った後、コンテナを終了すると、コンテナは Exited 状態に変わります。...
Web プロジェクトがどんどん大きくなると、CSS は天文学的な大きさと複雑さを増します。この問題を...
<br />テキストデザインでは、通常、テキストのレイアウト、つまりテキストをより美しく...
多くの場合、Linux システムに Web サービス アプリケーション (Tomcat、Apache...
mysql 行から列へ、列から行へ難しい文章ではないので、詳しく説明はしません。文章を読むときは、一...
プロフェッショナルな Web デザインは複雑で時間がかかります。 HTML と CSS フレームワー...
(1)実験環境youxi1 192.168.5.101 ロードバランサーyouxi2 192.168...
目次1. ミューテックス1. ミューテックスの初期化2. ミューテックスロックの関連特性と分類3. ...
1. 公式サイト http://dev.mysql.com/downloads/mysql/ から ...
重要なポイント: 1. CSS3 3Dアニメーションをマスターする2. ページめくり後のページ内容の...
「Enter != Submit」問題を実装するには、通常、「ボタンの種類」と「入力ボックスの数」か...
UI カットのプロセスでは、ページはヘッダー、コンテンツ、フッターの 3 つの部分で構成されることが...
データベースを表示show databases;データベースを作成するDATABASE データベース...