人間が読めるJavaScript:2人の専門家の話





誰もが専門家になりたいと思っています。しかし、それはどういう意味ですか?何年にもわたって、私は「専門家」と呼ばれる2つのタイプの人々に出くわしました。最初のタイプの専門家は、言語のすべての歯車を知っているだけでなく、それが有益であるかどうかに関係なく、これらすべての歯車を使用する人です。 2番目のタイプの専門家もすべての構文の微妙さを知っていますが、コードに関連するものと関連しないものの両方の多くの要因を考慮して、問題を解決するためのツールを選択する際により選択的です。



チームにどのような種類の専門家を求めているかを推測してみましょう。第二に、そうですか?これは、人間が読めるコード、他の人が理解でき、保守が容易なJavaScriptの文字列の作成に努めている種類の開発者です。しかし、「読みやすい」という特徴が定義されることはめったにありません。実際、それは通常、見る人の目にあります。では、これは私たちをどこに導くのでしょうか?私たちの目標が読み取り可能なコードである場合、私たちは何のために努力すべきですか?この場合、明らかに正しいか間違った選択がありますか?多くに依存します。



明白な選択



開発者の仕事を容易にするために、TC39は近年、他の言語から借用した多くの実証済みのパターンを含む、多くの新機能をECMAScriptに追加しました。ES2019で導入されたそのような革新の1つは、Array.prototype.flat()メソッド です。深さまたは無限大の引数を取り、配列を整列します。引数がない場合、配列のデフォルトの深さは1です。



この追加が表示される前は、配列を単一レベルに揃えるために次の構文が必要でした。



let arr = [1, 2, [3, 4]];
[].concat.apply([], arr);

// [1, 2, 3, 4]

      
      





flat()を追加することで、1つの表現関数だけで同じ機能を記述することができます。



arr.flat();

// [1, 2, 3, 4]

      
      





コードの2行目は読みやすいですか?もちろん。実際、両方の専門家はこれに同意するでしょう。



すべての開発者がフラット()の存在を認識しているわけではありません。ただし、flat()は理解できる動詞であり、ここで何が起こっているのかが明確であるため、これについて事前に知る必要はありません。concat.apply()よりもはるかに直感的です。



これは、新しい構文と古い構文のどちらが優れているかを自信を持って答えることができるまれなケースです。2つの構文に精通している両方の専門家が、2番目の構文を選択します。彼らは、より短く、より明確で、保守が容易なコード行を選択します。



しかし、選択と妥協は必ずしも簡単ではありません。



シラミを確認してください



JavaScriptの素晴らしい点は、その信じられないほどの多様性です。これがウェブ上のいたるところにある理由です。あなたの観点からそれが良いか悪いは別の質問です。



しかし、そのような多様性は、選択のパラドックスをもたらします。同じコードをさまざまな方法で記述できます。どちらが「正しい」かをどのように判断しますか?利用可能なすべてのオプションを知らず、それらが到達しないものを理解していない場合、そのようなソリューションにアプローチすることさえできません。 例としてmap()



使った関数型プログラミングを試してみましょう 。ここでは、いくつかの反復について説明します。これらはすべて同じ結果になります。



これが、すべてのマップ()の例の中で最も簡潔なバージョンです。文字数が最も少なく、すべて1行に収まります。このバージョンに基づいて構築します。



const arr = [1, 2, 3];

let multipliedByTwo = arr.map(el => el * 2);

// multipliedByTwo  [2, 4, 6]

      
      





次の例では、括弧という2つの文字を追加しています。何かを失ったことがありますか?購入しましたか?天候により、複数のパラメーターを持つ関数で常に括弧を使用する必要がありますか?私は思う-はい、そうです。ここに追加しても問題はありませんが、必然的に多くのパラメーターを使用して関数を作成する必要がある場合、コードの一貫性が大幅に向上します。実際、この記事の執筆時点で、Prettierこの制限が必要であること 判明しました。そこで、括弧なしで矢印関数を作成することができませんでした。



let multipliedByTwo = arr.map((el) => el * 2);
      
      







先に行く。中括弧とreturnステートメントを追加しました。これは現在、従来の関数定義のように聞こえ始めています。今のところ、関数ロジック全体がスズメに大砲を発射している限り、キーワードのように見えるかもしれません。ただし、関数に複数の行が含まれている場合は、この追加の構文が必ず必要になります。 1行より長い他の関数はないと想定していますか?疑わしいようです。



let multipliedByTwo = arr.map((el) => {

  return el * 2;

});

      
      





次に、矢印機能を完全に削除しました。以前と同じ構文を使用しますが、現在はfunctionキーワードを使用しています。この構文が機能しないシナリオはないため、これは興味深いことです。パラメータや文字列がいくつあっても問題はないので、ここでは均一性に優れています。このコードは最初の定義よりも長いですが、本当に悪いのでしょうか。これは、新しいプログラマーやJavaScriptに精通していないが、他の言語の人にどのような害を及ぼしますか? JavaScriptに精通している人は、比較するときにこの構文に混乱するでしょうか?



let multipliedByTwo = arr.map(function(el) {

  return el * 2;

});

      
      





最後に、最後のオプションである関数のみを渡します。また、timesTwoは、任意の構文を使用して記述できます。繰り返しますが、関数の名前を渡すことが問題になるシナリオはありません。しかし、一歩下がって、そのようなコードが誰かを混乱させる可能性があるかどうかを考えてみましょう。このコードベースを使い始めたばかりの場合、timesTwoはオブジェクトではなく関数であることは明らかですか?確かに、map()はここでのヒントとして役立ちますが、そのような詳細は見逃される可能性があります。 timesTwoが宣言されて初期化される場所はどうですか?それを見つけるのは簡単ですか?それが何をし、それが結果にどのように影響するかは明らかですか?これらの考慮事項はすべて重要です。



const timesTwo = (el) => el * 2;

let multipliedByTwo = arr.map(timesTwo);

      
      





ご覧のとおり、ここには明確な答えはありません。ただし、コードベースを構築するときに適切なオプションを選択できるのは、すべてのオプションとその制限を理解している場合のみです。特に、コードの一貫性を保つには、括弧、中括弧、および戻りキーワードが必要であることを知っています。



コードを書くときに注意しなければならない問題がいくつかあります。通常、パフォーマンスの問題 が最も一般的です。ただし、機能的に同一のコードフラグメントを比較する場合は、このコードを読まなければならない人々を考慮して選択する必要があります。



たぶん、新しい方が常に良いとは限りません



そのため、よく知られていない場合でも、両方の専門家が新しい構文を好むという非常に顕著な例を検討しました。また、多くの質問をするが、多くの回答を提供しない例も見てきました。それでは、以前に作成して削除したコードについて詳しく見ていきましょう。このコードは、あまり知られていない構文構造で問題を解決したときに、私を最初のタイプの専門家に変えました。それにより、同僚とコードベースを維持する便利さを無視しました。



割り当てを破棄すると、オブジェクト(または配列)から値を解凍できます。通常はこんな感じです。



const {node} = exampleObject;
      
      







ここでは、1行で、変数が初期化され、値が割り当てられます。しかし、そうではないかもしれません。



let node

;({node} = exampleObject)

      
      





コードの最後の行では、デストラクチャリングを使用して値が変数に割り当てられていますが、変数は1行上で宣言されています。これは頻繁に行われますが、多くの人はこれが可能であることに気づいていません。



このコードを詳しく見てみましょう。厄介なセミコロンがここに課されます。これは、セミコロンが行の終了に使用されていないコードにあります。ここでは、コマンドが括弧で囲まれ、中括弧が追加されています。ここで何が起こっているのかは完全に理解できません。専門家として私にはそのようなコードを書く権利がまったくなかったので、この行を読むのは難しいです。



let node

node = exampleObject.node

      
      





このコードは問題を解決します。それは機能し、そこで何が行われているのかは明らかであり、私の同僚はどこを見なくてもそれを理解するでしょう。破壊的な構文については、できるという理由だけで使用する べきではありません



コードがすべてではありません



これまで見てきたように、Expert-2の決定は、コードからのみ続行するかどうかを尋ねられることはめったにありません。ただし、各専門家がどのコードを書くべきかを見分けるのは簡単です。重要なのは、マシンはコードを読み取らなければならず、人々はそれを解釈しなければならないということです。したがって、コードに関連するだけではない要因を考慮する必要があります。



JavaScript開発チームで作業することは、メンバーが言語の微妙さにあまり没頭していない多言語チームで作業することとは異なるコード選択へのアプローチを持ちます。



例として、展開演算子とconcat()を比較してみましょう。



スプレッド演算子は数年前にECMAScriptに追加され、現在では非常に一般的です。これは、多くのことを実行できる一種のヘルパー構文です。特に、多数の配列を連結します。



const arr1 = [1, 2, 3];

const arr2 = [9, 11, 13];

const nums = [...arr1, ...arr2];

      
      





拡張演算子の可能性をすべて備えているため、その記号は自明ではありません。したがって、それが何をするのかわからない場合、それはあまり役に立ちません。どちらの専門家 も、JavaScriptの専門家が構文に精通していることを十分に計算できますが、専門家2は、多言語のプログラマーチームについて同じことを言うことができると考えています。したがって、Expert-2はconcat()メソッドを好む可能性があります。これは、コードのコンテキストからおそらく理解できる有益な動詞であるためです。



このコードスニペットは、拡張子演算子を使用した上記の例と同じ数値結果を提供します。



const arr1 = [1, 2, 3];

const arr2 = [9, 11, 13];

const nums = arr1.concat(arr2);

      
      





これは、人的要因がコード選択にどのように影響するかを示す一例にすぎません。さまざまなチームの人々がアクセスできるコードベースは、必ずしもすべてのクールな構文の革新に追いついていない、より厳しい標準によって管理されている可能性があります。次に、メインのソースコードから逸脱し、このコードで作業する人々の生活を複雑にしたり、楽にしたりする可能性のあるツールキットに関する他の要因を考慮する必要があります。テスト難しいように構造化できるコードがあります 。あなたを追い詰めるコードがあり、スケールアップしたり、新しい機能を追加したりすることはできません パフォーマンスが低下するコードがあり ますすべてのブラウザがサポートされている わけではない、アクセシビリティが不十分です。Expert-2は、彼の推奨事項でこれらすべての要素を考慮に入れています。



Expert-2は、命名要素も考慮に入れます。しかし、正直に言うと、ほとんどの場合専門家さえ ネーミングに対応していません。



結論



本当の専門家は、仕様からのすべてのきしみを適用する人ではなく、構文を合理的に展開し、よく考えられた決定を下すのに十分な仕様を知っている人です。このレベルに成長した専門家は、新しい専門家を準備することができます。



これは、自分自身を専門家と見なしている、または少なくとも専門家になることを熱望している私たちにとって何を意味しますか?これは、コードを書くときに自問する質問がたくさんあることを意味します。ターゲットオーディエンスである開発者を適切に評価します。あなたが書くことができる最良のコードは、いくつかの複雑な問題を解決するコードですが、定義上、あなたのコードベースを読む人には理解できます。



はい、それは非常に難しいです。そして、多くの場合、単一の答えはありません。ただし、各関数を作成するときは、上記について考慮する必要があります。






当社の 仮想マシンは、専門家のJavascript開発に使用できます。



上記のリンクを使用するか、バナーをクリックして登録すると、任意の構成のサーバーをレンタルした最初の月が10%割引になります。






All Articles