明瀺的なJavaScript機胜

画像







JavaScript蚀語のあたり知られおいない機胜に぀いおの次の蚘事を読んで、ブラりザコン゜ヌルでいく぀かの非垞識な゜リュヌションを静かにおしっこするずき、私はよく頭の䞭で蚀っおいたす。 結局のずころ、この蚀語は長い間巚倧なコミュニティを獲埗し、産業開発の驚くほど広い範囲をカバヌしおいたす。 もしそうなら、なぜ私たちは圌がすべおの人に理解され、これらすべおの具䜓的で「蚘憶に残る」構造を文字通り宣䌝する胜力をしばしば忘れるのでしょうか はっきりさせおください







トピックに関する掚論



このグラフォマニアはスキップできたす。







産業開発に぀いお話す堎合、ほずんどの堎合、サポヌトされるコヌドの芁件は、ビゞネスによっお蚭定されたタスクを解決するこずよりもさらに重芁です。 倚くの人にずっお、これは䞀郚の人にずっおは明らかです-䞀郚もちろん、たれなダルタニャンも芋぀かりたす。 コヌドがわかりやすいほど、コヌドのリスクほこりだらけの棚に眮かれ、私たちず埌継者が神経系に問題を起こすリスクが少なくなりたす。







JavaScriptの柔軟性が驚くべきこずであり、それが最倧の矎埳であるず同時に厄介な呪いでもありたす。 JavaScript開発者の道は長く、非垞に興味深いものです。曞籍ごず、蚘事ごずに吞収し、ナニヌクな経隓を積むこずができたすが、時にはそれは本圓に蚀語固有のものです。 蚀語の最も広い分垃ず、同時に倚くの蓄積され、䞎えられた非自明性は、この蚀語をほずんど偶像化する人々ず、それを䞍噚甚で揺れる暩利のカモず芋なす人々の2぀の前線の圢成に貢献したす。







そしお、すべおがうたくいきたすが、倚くの堎合、䞡方の分野の代衚者が同じプロゞェクトに取り組んでいたす。 そしお、通垞、受け入れられおいるすべおの慣行は、互いのコヌドを誀解理解するこずを望たず、無芖するこずさえするです。 そしお実際、 「私はJava開発者になりたしたが、あなたのものではありたせん」 。 JavaScriptのフォロワヌ自身が、 「JavaScriptを実際に誰も知らない」ず蚀っお、火に燃料を远加したす。 はい「jsで1行で蚘述できたす」 。 私は自分が䜙暇に異垞なプログラミングを乱甚しおいるず告癜したす...







限界の代わりになり、バリケヌドの䞡偎で人々ずそのコヌドを操䜜した経隓を積むず、この問題を感じ始めたす。 すべおの開発者が盞互に理解し合えば、ビゞネスラむンのレベルだけでなく、実装のレベルでも少なくずも少しは、蚈画やその他の䌚議の生産性が高たりたす。 悪名高い䜎音芁因はプロゞェクトにあたり圱響を䞎えたせん。1人のフロント゚ンダヌの病気が発生した堎合、チヌムの他のメンバヌは.jsファむルの䞀郚の行を修正するこずを軜disしたせん。 党員がより詳现な画像を持っおいる堎合、チヌム内およびそれ以降で知識を共有するプロセスは、党員にずっおより透明になりたす。 たあ、すべお同じように。







「フルグラス」や「Tシェむプ」今の蚀い方を教えおくださいを誰かに勧めるわけではありたせんが、JavaScriptコミュニティからだけであるずしおも、このカヌテンを少し䞊げおみたせんか これを行うには、コヌドを少しわかりやすくするだけで十分です。蚀語の柔軟性を掻甚しお、芋せびらかさないで理解しおください。







成長し責任を負う



JavaScriptは、むンタヌネットペヌゞの察話性ずリ゜ヌスの「接着」のための蚀語ずしおではなく、完党なクロスプラットフォヌムで非垞にスケヌラブルなアプリケヌションを䜜成するための匷力で十分なツヌルずしお、その圹割を長い間認識しおいたす。







もずもずWebデザむナヌ向けに蚭蚈されたこの「最も誀解されたプログラミング蚀語」は、急速に人気ず関連性が高たっおいるにもかかわらず、長い間氎を螏み続けおきたした。 ECMAScript 5.1の゚ディションに先行する13〜14幎間、暙準のいく぀かの重芁な倉曎を思い出すこず、たたはその開発のベクトルを理解するこずは困難です。 圓時、コミュニティは蚀語の゚コシステムの圢成に倚倧な貢献をしたしたプロトタむプ、jQuery、MooToolsなど。 開発者からこのフィヌドバックを受け取った埌、JavaScriptはバグに察しお重芁な䜜業を行いたした。2015幎のES6の倧芏暡な6幎間のリリヌスず、珟圚EC39Scriptの幎次リリヌスは、TC39委員䌚が仕様に新機胜を導入するプロセスを再蚭蚈したおかげです。







さお、アプリケヌションが十分に倧きくなったずき、ナヌザヌタむプを蚘述するためのプロトタむプOOPモデルは、通垞ずは異なるアプロヌチのために正圓化されなくなりたした。 たあ真剣に、それは䜕ですか







function Animal() { /* Call me via new and I will be the constructor ;) */ } function Rabbit() {} Rabbit.prototype = Object.create(Animal.prototype); Rabbit.prototype.constructor = Rabbit;
      
      





クラスは蚀語には衚瀺されたせんでしたが、構文は衚瀺されたした。 そしお、コヌドは䌝統的なクラス指向のパラダむムの支持者に利甚可胜になりたした







 class Animal { constructor() { /* Obviously, the constructor is here! */ } } class Rabbit extends Animal {}
      
      





珟圚、リリヌスの候補の段階では、クラスのプラむベヌトフィヌルドがありたす。 アンダヌスコアで私有財産を呜名するこずで合意するこずで、遅かれ早かれお互いの笑い声が止たるずは信じられたせん。







同時に、関数が1次オブゞェクトであり、䞀定の偶然性がある蚀語では、非垞に䞀般的です。







 let that = this; setTimeout(function() { that.n += 1; }, 1000);
      
      





そしお、ここでこのコンテキストずJavaScriptの閉鎖に぀いおの説明が始たりたす。これは、倖郚の開発者1人おきを怖がらせたす。 しかし、倚くの堎合、この蚀語はFunction.prototype.bindなどを明瀺的に䜿甚するこずで、䞍必芁な驚きを回避したす。







 setTimeout(() => this.n += 1, 1000);
      
      





たた、矢印関数も取埗したしたが、これらは実際には関数であり、機胜的なむンタヌフェむスではありたせんはい、Java。 配列を操䜜するためのメ゜ッドの拡匵セットず䞀緒に、通垞の宣蚀的なペむラむン蚈算を蚘述するのにも圹立ちたす。







 [-1, 2, -3, 4] .filter(x => x > 0) .map(x => Math.pow(2, x)) .reduce((s, x) => s + x, 0);
      
      





蚀語はそれ自䜓がマルチパラダむム的であるず正しく考えおいたす。 しかし、いく぀かの関数のシグネチャに関する簡単な䟋を次に瀺したす。







 function ping(host, count) { count = count || 5; /* send ping to host count times */ }
      
      





最初に、通りかかった人は、おそらく関数は最初の匕数しか受け取れないずいう質問をし、次にこの堎合のカりントはブヌル倀になりたす 実際、この関数には2぀の甚途がありたす 。 カりントありずカりントなしです。 しかし、これは完党に自明ではありたせん。実装を芋お理解する必芁がありたす。 JSDocを䜿甚するず圹立぀堎合がありたすが、これは䞀般的な方法ではありたせん。 そしお、ここではJavaScriptが前進し、オヌバヌロヌドではなく、少なくずもデフォルトパラメヌタのサポヌトが远加されたした。







 function ping(host, count = 5) { /* ... */ }
      
      





芁玄するず、JavaScriptには、ゞェネレヌタヌ、むテレヌタヌ、 セットコレクションずマップディクショナリヌ、型付き配列、さらには正芏衚珟でさえ、 埌読みサポヌトで満足できるものがたくさんありたした 。 この蚀語は、倚くのこずに適し、すべおの人に芪しくなるためにすべおを行いたす。







明癜なものぞの奜たしい道



蚀語自䜓は確かによくできおおり、それに぀いお議論するのは難しいです しかし、䜕が悪いのでしょうか JavaScriptがどういうわけか異なるこずを䞖界䞭に垞に思い出させるのはなぜですか 広く䜿甚されおいるいく぀かの手法の䟋を芋お、それらの適切性に぀いお尋ねたしょう。







タむプキャスト



はい。JavaScriptには動的で匱い型システムがあり、あらゆるものに察しお操䜜を実行でき、暗黙的に倉換を実行できたす。 しかし、倚くの堎合、明瀺的なキャストが䟝然ずしお必芁であり、次のこずが芳察できたす。







 let bool = !!(expr); let numb = +(expr); let str = ''+(expr);
      
      





これらのトリックはすべおのJavaScript開発者に知られおおり、「すばやく」䜕かを䜕かに倉えるこずができるず蚀っおいるずいう事実に動機付けられおいたす。ここでの速床ずは、短い蚘録を意味したす。  開発者が印刷可胜な文字を非垞に心配しおいる堎合は、お気に入りのIDEで、必芁なラむブテンプレヌトたたはオヌトコンプリヌトを簡単に構成できたす。 そしお、もし-公開されたコヌドのサむズに察しお、私たちは垞に難読化ツヌルを介しおそれを実行したす。 なぜ







 let bool = Boolean(expr); let numb = Number(expr); let str = String(expr);
      
      





結果は同じで、誰にでも明らかです。







文字列の倉換にはtoStringがありたすが、数倀の倉換には興味深いvalueOfがあり 、これもオヌバヌラむドできたす。 「未経隓者」をst迷者に導入する叀兞的な䟋







 let timestamp = +new Date;
      
      





ただし、 Dateには既知のgetTimeメ゜ッドがありたす。それを䜿甚しおみたしょう。







 let timestamp = (new Date()).getTime();
      
      





たたは既補の機胜







 let timestamp = Date.now();
      
      





暗黙の型倉換を掻甚する必芁はたったくありたせん。







論理挔算子



論理挔算子AND&&ずOR||には特別な泚意が払われたす。これらはJavaScriptでは完党に論理的ではありたせん。あらゆる皮類の倀を受け入れお返したす。 論理匏蚈算機の操䜜の詳现に぀いおは説明したせんが、䟋を怜蚎したす。 関数で以前に提瀺されたオプション







 function ping(host, count) { count = count || 5; /* ... */ }
      
      





次のようになりたす。







 function ping(host, count) { // OR arguments.length? if (typeof count == 'undefined') { count = 5; } /* ... */ }
      
      





このような怜蚌はより身近なものであり、堎合によっおは間違いを避けるのに圹立ちたす。







むしろ、最初にJavaScriptパスを遞択した開発者にずっおは野avなようです。 しかし、他のほずんどの人にずっお、このコヌドは本圓にワむルドです







 var root = (typeof self == 'object' && self.self === self && self) || (typeof global == 'object' && global.global === global && global);
      
      





はい、それはコンパクトです、そしお、はい、人気のある図曞通はそれを買う䜙裕がありたす。 ただし、JavaScriptの寄皿者ではなく、割り圓おられた時間内にビゞネス䞊の問題を解決する開発者によっおコヌドが読み取られるため、悪甚しないでください。







そのようなパタヌンは、たったく発生する可胜性がありたす。







 let count = typeof opts == 'object' && opts.count || 5;
      
      





これは通垞の䞉項挔算子よりも明らかに短いですが、このコヌドを読むずき、最初に芚えおおくべきこずは、䜿甚する操䜜の優先順䜍です。







同じArray.prototype.filterに枡す述語関数を䜜成する堎合、戻り倀をブヌル倀でラップするのが良い方法です。 この関数の目的はすぐに明らかになり、蚀語に「正しい」論理挔算子がある開発者の間で䞍協和音はありたせん。







ビット挔算



いく぀かのチュヌトリアルでも提䟛されおいる、ビット単䜍のNOTNOTを䜿甚しお、配列内の芁玠たたは文字列内の郚分文字列の存圚を確認する䞀般的な䟋







 if (~[1, 2, 3].indexOf(1)) { console.log('yes'); }
      
      





これはどのような問題を解決したすか indexOfは芁玠のむンデックスたたは-1を取埗し、チルダは1を远加しお笊号を倉曎するため、 == -1をチェックする必芁はありたせん。 したがっお、むンデックスが-1の堎合、匏は「停」になりたす。







ただし、コヌドの重耇は別の方法で回避できたす。他の目的でビット挔算を䜿甚するよりも、すべおのナヌザヌが行うように、䞀郚のutilsオブゞェクトの別の関数にチェックを入れたす。 このためにlodashにinclude関数があり、それは機胜したせん アナルセックス チルダ。 ECMAScript 2016ではArray.prototype.includesメ゜ッドが修正されたため、喜ぶこずができたす行にも1぀ありたす。







しかし、そこにありたした 別のチルダXORずずもにを䜿甚しお数倀を䞞め、小数郚分を砎棄したす。







 console.log(~~3.14); // 3 console.log(2.72^0); // 2
      
      





ただし、これらの目的にはparseIntたたはMath.floorがありたす。 ここでのビット挔算は、他の算術よりも優先床が䜎いため、コン゜ヌルでコヌドをすばやく入力するのに䟿利です。 しかし、コヌドレビュヌでは、芋逃さない方が良いでしょう。







構文および蚀語構成



䞀郚の奇劙な慣行は、特定のセクションに起因するこずは困難です。 たずえば、コンストラクタヌを呌び出すずき、括匧はオプションであり、次の2぀の匏は同䞀であるず蚀いたす。







 let rabbit = new Rabbit(); let rabbit = new Rabbit;
      
      





そしおそれは本圓に しかし、なぜ最初から質問を䜜成するのですか すべおの蚀語がそのような「機胜」を誇るわけではありたせん。 そしお、もしそれでもいいのであれば、それをプロゞェクト党䜓の合意にしたしょう。 そうでなければ、違いがあるずいう誀った感芚がありたす。







倉数のセットを宣蚀する同様の状況。 varおよびletディレクティブの構文を䜿甚するず、耇数の倉数をコンマで区切っお䞀床に宣蚀および定矩できたす。







 let count = 5, host, retry = true;
      
      





誰かが読みやすくするために改行を䜿甚しおいたすが、いずれにしおも、この構文は䞀般的な蚀語では䞀般的ではありたせん。 誰も手を挙げお、あなたがこのように曞くかどうか尋ねたせん







 let count = 5; let retry = true; let host;
      
      





繰り返したすが、プロゞェクト/䌁業レベルで良いスタむルに関する合意がある堎合、質問はありたせん。 気分に合わせお構文のバリ゚ヌションを組み合わせる必芁はありたせん。







IIFEなど、蚀語には完党に特定の構造があり、定矩の堎所ですぐに関数を呌び出すこずができたす。 党䜓の秘trickは、パヌサヌが関数宣蚀ではなく関数匏を認識するこずです。 そしお、これはさたざたな方法で行うこずができたす叀兞的に括匧で囲む、 voidたたはその他の単項挔算子を䜿甚する。 そしお、それに぀いお玠晎らしいこずは䜕もありたせん 唯䞀のオプションを遞択する必芁があり、それを必芁なく残さないでください







 (function() { /* ... */ }());
      
      





パヌサヌをハックするためにオペレヌタヌを䜿甚する必芁はありたせん。 新芏参入者がプロゞェクトに来たずき、アプリケヌションのビゞネスロゞックに浞し、これらの感嘆笊や空癜がすべおスパむされた堎所からの説明を提䟛したくない。 たた、2番目の叀兞的なブラケット゚ントリず、このテヌマに関するCrockfordからの興味深いコメントもありたす。







ES6のクラス構文の出珟には、通垞のアクセス修食子が付随しおいたせんでした。 たた、開発者はクラスをじっくり芋たり、プラむバシヌを芳察したい堎合がありたす。 これはこのフランケンシュタむンのコヌドに぀ながりたす







 class Person { constructor(name) { let _name = name; this.getName = function() { return _name; } } toString() { return `Hello, ${this.getName()}`; } }
      
      





぀たり、コンストラクタヌでむンスタンスのアクセサヌが䜜成され、クロヌゞャヌを介しおロヌカルプロパティ倉数にアクセスするこずでプラむバシヌが実珟されたす。 この䟋はLacconcinoにかなり䌌おいたすが、ドキュメント化されたフレヌムワヌク゜リュヌションを構築しない限り、これは完党にスケヌラブルなアプロヌチではありたせん。 玳士、利甚可胜なクラスおよびプラむベヌトフィヌルドの暙準化を埅぀、たたは人気のあるパタヌンモゞュヌルを䜿甚しおみたしょう。 ここで䜕らかの䞭間ミックス゜リュヌションを䜜成するこずは、クラスがクラスでなくなり、コヌドがわかりやすいため、自分にずっおは非垞に重芁です。







芁玄するず、圌はプロゞェクトで採甚されおいるスタむルガむド、リンタヌの蚭定、たたはプロゞェクトにJavaScript以倖のコンポヌネントを提䟛しおいる同僚ず単にコヌドの断片ず、垞識を共有したす。 この蚀語には、文字通りすべおの兞型的なタスクに察しおいく぀かのオプションが甚意されおいるため、互いの理解を深め、共通の分母に分類するこずは難しくありたせんたたはほずんど。







ミスアドベンチャヌ



このトピックは確かに党䜓論的であり、さらに倚くの䟋がありたすが、蚘事の䞻なメッセヌゞは、これを回避できるJavaScriptの非自明性を悪甚すべきではないずいうこずです。 この蚀語の性質は独特です。゚レガントで衚珟力豊かな「頑固な」皋床たで゜リュヌションを䜜成できるほか、誰もが理解しやすくアクセスできるようになっおいたす。 JavaScriptは「自分自身を眰する」たたは「善意ず倱敗の山に埋もれおいる」ずいう埓来の知恵に根本的に反察したす。 なぜなら、今では奇劙さのほずんどは蚀語ではなく、開発者の文化ずその呚りに圢成された無関心ではないによっお実蚌されおいるからです。








All Articles