人々が読むこずができるコヌドを曞くこずの重芁性

コヌドを再床調べる必芁がないずきに、䞀気にプロゞェクトを完了する必芁がありたしたか ほずんどない。 叀いプロゞェクトで䜜業する堎合、このコヌドがどのように機胜するかを理解するのに時間を無駄にしたくないでしょう。 コヌドが読みやすい堎合は、補品のメンテナンスが容易であり、あなた、同僚、たたは埓業員は満足しおいたす。



刀読䞍胜なコヌドの鮮明な䟋はJS1kコンテストにありたす。その目的は、1024文字以䞋で構成される最高のJSアプリケヌションを䜜成するこずです。 JSF * ckに぀いおも同じこずが蚀えたす。JSF* ckは、6぀の異なる文字のみを䜿甚しおJSコヌドを蚘述する非垞に独特なプログラミングスタむルです。 これらのサむトに投皿されたコヌドを芋お、ここで䜕が起こっおいるのかを理解しようずしお頭を悩たすでしょう。 同様のコヌドを蚘述し、1か月埌にバグを修正しようずするずどうなるか想像しおみおください。



定期的にネットサヌフィンをしたり、むンタヌフェむスを䜜成したりする堎合、すべおのナヌザヌが必芁ずするわけではない倧きなフォヌムに蚘入するのに倚くの時間ず忍耐が必芁であるこずをご存じでしょう。 コヌドに぀いおも同じこずが蚀えたす。 読みやすくなればなるほど、それを長時間䜿甚するのが楜しくなりたす。 たたは、少なくずもコンピュヌタヌを窓の倖に攟り出したいずいう欲求はありたせん。



この蚘事では、萜ずし穎を避けおコヌドを読みやすくするためのさたざたなトリックずトリックを取り䞊げたす。



もずの蚘事 https : //www.sitepoint.com/importance-of-code-that-humans-can-read/



コヌド分​​離



フォヌムずの類䌌性に戻りたす画面に衚瀺しやすくするために、フォヌムを郚分に分割する堎合がありたす。 同じこずをコヌドで行うこずができたす。 郚分に分割するず、ゞャングルを通過するこずなく目的のフラグメントを芋぀けやすくなりたす。



ファむルの最適化



私たちは䜕幎もの間りェブの最適化を行っおきたしたが、JSファむルも䟋倖ではありたせん。 HTTP / 2を埅っおいる間にミニファむを行うこずで、耇数のスクリプトを1぀に結合しおリク゚ストを保存したした。 今日では、ファむルを凊理するタスクをGulpやGruntなどのツヌルに任せお、奜きなように䜜業できたす。 ぀たり、必芁に応じおプログラムを䜜成し、特別に蚓緎されたアプリケヌションに最適化たずえば、連結の実行を実行させるこずができたす。



//     API var getUsersRequest = new XMLHttpRequest(); getUsersRequest.open('GET', '/api/users', true); getUsersRequest.addEventListener('load', function() { //  -   }); getUsersRequest.send(); //--------------------------------------------------- //    . // ,       . //--------------------------------------------------- //      API var getPostsRequest = new XMLHttpRequest(); getPostsRequest.open('GET', '/api/posts', true); getPostsRequest.addEventListener('load', function() { //  -   }); getPostsRequest.send();
      
      





機胜



再利甚可胜なコヌドのブロックを䜜成できたす。 通垞、関数の内容により、関数の開始点ず終了点を簡単に理解できたす。 小さな関数を曞くのは良い習慣です-10行以内。 関数の名前が正しい堎合、呌び出されたずきに䜕をするかを簡単に理解できたす。 以䞋では、呜名芏則に戻りたす。



 //     API function getUsers(callback) { var getUsersRequest = new XMLHttpRequest(); getUsersRequest.open('GET', '/api/users', true); getUsersRequest.addEventListener('load', function() { callback(JSON.parse(getUsersRequest.responseText)); }); getUsersRequest.send(); } //      API function getPosts(callback) { var getPostsRequest = new XMLHttpRequest(); getPostsRequest.open('GET', '/api/posts', true); getPostsRequest.addEventListener('load', function() { callback(JSON.parse(getPostsRequest.responseText)); }); getPostsRequest.send(); } //        //     getUsers(function(users) { //  -   }); getPosts(function(posts) { //  -   });
      
      





䞊蚘のコヌドは読みやすいです。 䞡方の機胜はほが同じであるこずに泚意しおください。 「 繰り返さない 」ずいう原則に埓うこずができたす。これにより、コヌド内の順序を維持できたす。



 function fetchJson(url, callback) { var request = new XMLHttpRequest(); request.open('GET', url, true); request.addEventListener('load', function() { callback(JSON.parse(request.responseText)); }); request.send(); } //       //     fetchJson('/api/users', function(users) { //  -   }); fetchJson('/api/posts', function(posts) { //  -   });
      
      





しかし、POST芁求を䜿甚しお新しいナヌザヌを䜜成する堎合はどうでしょうか。 次の2぀のオプションがありたす。





しかし、オブゞェクト指向プログラミングのおかげで、構成可胜なワンタむムオブゞェクトを䜜成するこずにより、䞡方のオプションを最倧限に掻甚できたすが、コヌドの保守はかなり簡単です。

泚 オブゞェクト指向JavaScriptの基本だけが必芁な堎合は、次のビデオをご芧ください オブゞェクト指向JavaScript の完党なガむド 。



オブゞェクト指向プログラミング



しばしばクラスず呌ばれる、コンテキスト䟝存の関数のクラスタヌであるオブゞェクトを怜蚎しおください。 このようなオブゞェクトは、別のファむルに完党に収たりたす。 この堎合、XMLHttpRequestの基本的なラッパヌを䜜成できたす。 2015幎たで、JavaScriptはプロトタむプ指向の蚀語であり、クラスがなかったこずに泚意しおください。 この事実は、プロトタむプの継承ずずもに、コヌドのフォヌマットに関する特定の芏則を芏定しおいたす。



HttpRequest.js



 function HttpRequest(url) { this.request = new XMLHttpRequest(); this.body = undefined; this.method = HttpRequest.METHOD_GET; this.url = url; this.responseParser = undefined; } HttpRequest.METHOD_GET = 'GET'; HttpRequest.METHOD_POST = 'POST'; HttpRequest.prototype.setMethod = function(method) { this.method = method; return this; }; HttpRequest.prototype.setBody = function(body) { if (typeof body === 'object') { body = JSON.stringify(body); } this.body = body; return this; }; HttpRequest.prototype.setResponseParser = function(responseParser) { if (typeof responseParser !== 'function') return; this.responseParser = responseParser; return this; }; HttpRequest.prototype.send = function(callback) { this.request.addEventListener('load', function() { if (this.responseParser) { callback(this.responseParser(this.request.responseText)); } else { callback(this.request.responseText); } }, false); this.request.open(this.method, this.url, true); this.request.send(this.body); return this; };
      
      





app.js



 new HttpRequest('/users') .setResponseParser(JSON.parse) .send(function(users) { //  -   }); new HttpRequest('/posts') .setResponseParser(JSON.parse) .send(function(posts) { //  -   }); //    new HttpRequest('/user') .setMethod(HttpRequest.METHOD_POST) .setBody({ name: 'Tim', email: 'info@example.com' }) .setResponseParser(JSON.parse) .send(function(user) { //  -    });
      
      





定数は、コンストラクタヌですぐに宣蚀する必芁があるこずに泚意しおください。 䞊蚘で䜜成したHttpRequestクラスは、倚くのAPI呌び出しを䜿甚しお広範囲に蚭定できるようになりたした。 その実装メ゜ッド呌び出しのチェヌンがより耇雑であるこずが刀明したずいう事実にもかかわらず、クラス自䜓の保守は簡単です。 実装ずコヌドを再利甚する胜力ずのバランスを芋぀けるプロセスは困難な堎合があり、プロゞェクトによっお異なりたす。



オブゞェクト指向プログラミングぞの倧きな远加は、デザむンパタヌンです。 それ自䜓では、読みやすさは向䞊したせんが、䞀貫性はそれを実珟したす



人に優しい構文



ファむル、関数、オブゞェクト-これらは単なる倧たかなガむドラむンです。 コヌドを簡単にスキャンできたす。 しかし、コヌドを読みやすくするこずは、はるかに埮劙な技術です。 现郚を现かくするこずで、画像を完党に倉曎できたす。 たずえば、倚くの堎合、垂盎線を䜿甚する゚ディタヌでは、行の長さは80文字に制限されおいたす。 しかし、他にも倚くのニュアンスがありたす



呜名



適切な呜名のおかげで、倉数の皮類やこの関数の機胜を理解するこずなく、特定の芁玠を即座に認識するこずができたす。



関数は通垞、ラクダのスタむルで呌び出されたす。最初に動詞、次に䞻語が来たす。



 function getApiUrl() { /* ... */ } function setRequestMethod() { /* ... */ } function findItemsById(n) { /* ... */ } function hideSearchForm() { /* ... */ }
      
      





倉数名に぀いおは、 逆ピラミッド手法を䜿甚しおみおください。最初に件名が衚瀺され、次にプロパティが衚瀺されたす。



 var element = document.getElementById('body'), elementChildren = element.children, elementChildrenCount = elementChildren.length; //   ,      “color” var colorBackground = 0xFAFAFA, colorPrimary = 0x663399; //   ,     “background” var backgroundColor = 0xFAFAFA, backgroundImages = ['foo.png', 'bar.png']; //     var headerBackgroundColor = 0xFAFAFA, headerTextColor = 0x663399;
      
      





そのような堎合、連想配列JSのオブゞェクトを䜿甚する方が適切です。その埌、色の接頭蟞を取り陀くこずができ、読みやすさが向䞊したす。



 var colors = { 'backgroundRed' : red, 'primary': greeen };
      
      





たた、通垞の倉数ず特殊倉数の区別を匷調するこずも重芁です。 たずえば、定数名は倚くの堎合アンダヌスコアで倧文字になりたす。



 var URI_ROOT = window.location.href;     ,   . function FooObject { // ... }
      
      





略語では、ニュアンスもありたす。 誰かが倧文字でのみ、キャメルスタむルで誰かを曞いおいたす。 前者の堎合、略語を認識するのが難しい堎合がありたす。



しかし、䞀般に、すべおは開発者たたはチヌムが採甚したコヌディングスタむルに䟝存したす。 垞に遞択された1぀のスタむルを順守し、そのコンプラむアンスを確認し、リンタヌを䜿甚する必芁がありたす。



コンパクトで最適化



倚くのコヌドベヌスでは、文字数を枛らしたり、アルゎリズムのパフォヌマンスを向䞊させるように蚭蚈された「特別な」コヌドを芋぀けるこずができたす。



コンパクトなコヌドの䟋は、単䞀行のスクリプトです。 残念ながら、圌らはしばしばハックやあいたいな構文を䜿甚したす。 原則ずしお、ネストされた䞉項挔算子が䜿甚されたす。 コンパクトであるにもかかわらず、通垞のif



ずは異なり、䜕をしおいるのかを理解しようずしお数秒を費やす必芁がありたす。 そのため、構文の略語には泚意しおください。



適切なアプロヌチは、本番環境でコヌドを瞮小するこずです。 ファむルの重量は軜く、ブラりザにより高速にロヌドされ、ペヌゞ党䜓のロヌド時間が短瞮されたす。 しかし、生産に䟿利な瞮小ファむルは、開発においお完党に䞍䟿です。 したがっお、prodずvirgoで䜿甚されるJSを分離し、各ファむルの2぀のバヌゞョン瞮小および完党を保存し、構成で指定された環境に埓っお䜿甚を切り替えるこずができたす。



 // , -    ! var state = isHidden ? 'hidden' : isAnimating ? 'animating' : ''; // , -   ! var state = ''; if (isAnimating) state = 'animating'; if (isHidden) state = 'hidden';
      
      





パフォヌマンスを改善するために蚭蚈されたマむクロ最適化は、倚くの堎合効果的ではありたせん。 そしお、ほずんどの堎合、生産性の䜎いものよりも読みにくくなりたす。



 //     $el[0].checked; //    ,    // : http://jsperf.com/prop-vs-ischecked/5 $el.prop('checked'); $el.is(':checked'); $el.attr('checked');
      
      





耇数のポむントチェックの堎合、スむッチを䜿甚するこずをお勧めしたす。ポむント倀のチェックが発生するこずは意味的に明確です。



JavaScriptコンパむラヌはコヌドの最適化をうたく行っおおり、長幎にわたっおその最適化を行っおきたした。 最適化されたコヌドず最適化されおいないコヌドの違いが目立たない堎合、数千たたは数癟䞇の操䜜を䜿甚するずきにその郚分が芳察される堎合、読みやすさを優先する方が良いです。



非コヌド



それを皮肉だず考えおください。しかし、コヌドを読みやすくする最善の方法は、実行䞍可胜な構文を远加するこずです。 それを非コヌドず呌びたしょう。 ただし、JSは䞀般的に、無芖すべきではないコヌドフォヌマット暙準を受け入れおいるこずを忘れないでください。 以䞋で説明したす。



くがみ



確かに、少なくずも䞀床はすべおの開発者が自分の人生でコヌドを別の開発者に曞き蟌むのを手䌝ったり、すべおのスペヌスずむンデントが削陀された瞮小コヌドを怜査したりしたした。 初めお、これはあなたにずっお驚きだったに違いありたせん。 デザむンやタむポグラフィなどのさたざたな芖芚分野では、空き領域は塗り぀ぶしず同じくらい重芁です。 ほずんどの堎合、それらの間の埮劙なバランスを芋぀けたいず思うでしょう。 このバランスに関する意芋の範囲は、䌚瀟、チヌム、および特定の開発者によっお異なりたす。 幞いなこずに、䞀般的に受け入れられおいるルヌルがいく぀かありたす。





他のルヌルは、䞀緒に働く人ず話し合う必芁がありたす。 ただし、蚭蚈するコヌドのスタむルに関係なく、重芁なのは䞀貫性です。



 function sendPostRequest(url, data, cb) { //        var requestMethod = 'POST', requestHeaders = { 'Content-Type': 'text/plain' }; // ,    XMLHttpRequest var request = new XMLHttpRequest(); request.addEventListener('load', cb, false); request.open(requestMethod, url, false); request.send(data); }
      
      





コメント



むンデントず同様に、コメントはコヌドを完党にたばらにするこずができたす。 同時に、コヌドの説明が含たれおいたす。 必ずコメントを远加しおください





 //     var sum = values.reduce(function(previousValue, currentValue) { return previousValue + currentValue; });
      
      





すべおの修正が明らかなわけではありたせん。 远加情報の導入により、倚くのこずが明らかになりたす。



 if ('addEventListener' in element) { element.addEventListener('click', myFunc); } // IE8     .addEventListener, //      .attachEvent // http://caniuse.com/#search=addEventListener // https://msdn.microsoft.com/en-us/library/ms536343%28VS.85%29.aspx else { element.attachEvent('click', myFunc); }
      
      





関数のドキュメントを䜿甚するずきは、コヌド内でコメントを䜿甚せず、コメントを必芁ずしない耇数行の関数を䜜成するこずをお勧めしたす。 䜜業䞭は、 todoコメントを䜿甚できたす。倚くのIDEはそれらの怜玢をサポヌトしおいたす。 todoを䜿甚するず、ファむナラむズたたは完了する必芁のあるコヌドピヌスがマヌクされたす。 そのため、他の開発者は、蚈画ず蚭蚈で定められたロゞックであるアプロヌチを理解しやすくなりたす。 todoを適切な堎所に眮くこずは非垞に䟿利です。



統合ドキュメント



オブゞェクト指向゜フトりェアを䜜成するずき、埋め蟌みドキュメントはコヌドをより自由にし、通垞のコメントにするこずができたす。 たた、プロパティずメ゜ッドの機胜の目的ず詳现に぀いおも説明したす。 倚くのIDEは、ドキュメント生成ツヌルを䜿甚するヒントずしお組み蟌みのドキュメントを䜿甚したす 理由に関係なく、コヌドでドックを蚘述するこずは優れた゜リュヌションです。



 /** *  HTTP- * @constructor * @param {string} url */ function HttpRequest(url) { // ... } /** *    * @param {Object} headers * @return {HttpRequest} */ HttpRequest.prototype.setHeaders = function(headers) { for (var header in headers) { this.headers[header] = headers[header]; } //    return this; };
      
      





解説にはparam {Object}ヘッダヌが瀺されおいたすが、このパラメヌタヌに保存されお枡されるものの説明を提䟛する方が適切です。 この情報は、パラメヌタヌ自䜓の盎埌に瀺すこずをお勧めしたす。 これがHolds success request headers200であるずしたしょう。 次に、コメントは次のようになりたす。



@param {Object} headers Holds success request headers( 200 )







機胜に関するドキュメントの圢匏はさたざたですが、チヌム党䜓が同じ圢匏を䜿甚するこずが非垞に重芁です。 開発者が1人の堎合、異なる堎所で同じ圢匏を䜿甚する必芁がありたす。 仮パラメヌタの説明では、仮パラメヌタのTIを瀺すこずが必須です。 いく぀かのIDEは、間違った型の倉数が枡された堎合、その堎でプロンプトを衚瀺したす。 JSは動的な型指定を備えた蚀語であり、IDEが゚ラヌをスロヌするずいう事実ではありたせんが、そのようなドキュメントを解析するずきに倚くの゚ラヌを回避できたす。



コヌルバックのなぞなぞ



むベントず非同期呌び出しはJavaScriptの優れた機胜ですが、倚くの堎合、コヌドの可読性を損ないたす。

通垞、非同期呌び出しにはコヌルバックが䌎いたす。 時にはそれらを順番に実行する必芁があり、時にはそれらすべおの準備が敎うたで埅぀ほうが良い堎合がありたす。 関数のドキュメントで、コヌルバック関数ぞの参照を䜜成する必芁がありたす。これにより、コヌルバック関数に簡単に移動したり、説明を確認したりできたす。



 function doRequest(url, success, error) { /* ... */ } doRequest('https://example.com/api/users', function(users) { doRequest('https://example.com/api/posts', function(posts) { //  -     }, function(error) { //   /api/posts }); }, function(error) { //   /api/users });
      
      





䞡方の問題を解決するために、PromiseオブゞェクトがES2015ES6ずも呌ばれたすに実装されたした。



 function doRequest(url) { return new Promise(function(resolve, reject) { //   //     resolve(response) //     reject(error) }); } //    doRequest('https://example.com/api/users') //     ,  .then() .then(function(users) { /* ... */ }) //    Promise   reject(),  .catch() .catch(function(error) { /* ... */ }); //    Promise Promise.all([ doRequest('https://example.com/api/users'), doRequest('https://example.com/api/posts') ]) .then(function(responses) { /* ... */ }) .catch(function(error) { /* ... */ });
      
      





コヌドの䞀郚を远加する必芁がありたしたが、通垞は正しく解釈する方が簡単でした。 Promiseの詳现に぀いおは、 JavaScript Goes Asynchronousand It's Awesomeをご芧ください。



ES6 / ES2015



ES2015仕様を読んだ堎合、この蚘事のすべおのコヌド䟋が叀いバヌゞョンのものであるこずにお気づきかもしれたせんPromiseオブゞェクトを陀く。 ES6には非垞に幅広い可胜性がありたすが、ひどい読みやすさに関しおは倚くの䞍満がありたす。



倪い矢印の構文は、芪スコヌプからthis



を継承する関数を定矩したす。 少なくずも、このために䜜成されたした。 たた、通垞の関数を定矩するために䜿甚するのも魅力的です。



 var add = (a, b) => a + b; console.log(add(1, 2)); // 3
      
      





別の䟋は、残りずスプレッドの構文です。



 /** *    * @param {Array} numbers * @return {Number} */ function add(...numbers) { return n.reduce(function(previousValue, currentValue) { return previousValue + currentValue; }, 0); } add(...[1, 2, 3]); /** *  a, b  c * @param {Number} a * @param {Number} b * @param {Number} c * @return {Number} */ function add(a, b, c) { return a + b + c; } add(1, 2, 3);
      
      





ES2015仕様では、非垞に䟿利ですが、あいたいで、時には混乱を招く構文が批評家のタヌゲットになっおいたす。 しかし、私たちはこれらの機䌚を攟棄するこずに぀いお話しおいるのではなく、単に泚意しおそれらを䜿甚しおいたす。



おわりに



コヌドの可読性ず保守性を維持するには、プロゞェクトのあらゆる偎面を芚えおおく必芁がありたす。 ファむルシステムから小さな構文バリ゚ヌションたで、すべおが重芁です。 これは、各参加者にすべおのルヌルを垞に順守させるこずが難しいため、チヌムで䜜業する堎合に特に顕著です。 問題の䞀郚はコヌドの修正によっお解決されたすが、それでも゚ラヌの可胜性がありたす。 幞いなこずに、いく぀かの䟿利なツヌルがありたす。





コヌドの耇雑さを分析するこずは非垞に重芁であり、分析にはさたざたなアプロヌチがありたす。 詳现に぀いおは、 http  //jscomplexity.org/complexityをご芧ください。



品質ずスタむルを維持するためのツヌルに加えお、読みやすさを改善するためのツヌルがいく぀かありたす。 さたざたな構文匷調スキヌムを詊すか、ミニマップを䜿甚しおスクリプトを階局的に評䟡したす Atom 、 Brackets 。 たずえば、 https//github.com/airbnb/javascriptは、かなり䞀般的なJSコヌドのフォヌマット暙準です。 コヌドのフォヌマットず暙準は䜿甚するツヌルに䟝存するこずに泚意しおください。 たずえば、ReactずJSXの堎合、他のスタむル芁件がありたす。



All Articles