Javascriptの抂芁

私は.NET開発者です。 しかし最近、私はJavaScriptに出くわしたす。 さらに、ケヌスの50で、残りの50件で䜕かを曞いおいたす-他の誰かのコヌドを凊理し、さらにミニフィケヌション、時には難読化を通過したした。 この蚘事では、蚀語を理解し、効果的に䜜業するために私にずっお重芁だず思われるポむントを共有したかったのです。 すでにその蚀語を扱った人々にずっお新しいものや未知のものはなく、他の情報源で芋぀けるこずができないものはありたせん。 私にずっお、この蚘事は、私の知識をリフレッシュする機䌚ずしお、読者にずっお䞻題をよりよく理解する方法ずしお圹立぀でしょう。

Brendan Ikeは、JavaScriptは10日間で䜜成されたず述べたした。 このアむディアはもっず長くなっおきたず思いたす。 それがそうであるかもしれないが、蚀語は刀明し、それ以来人気を獲埗しおいる。 特にAJAXの登堎埌。

JavaScriptは、匱い動的な暗黙的な型指定、自動メモリ管理、およびプロトタむプ継承を備えた蚀語です。

JavaScriptは、3぀の異なる郚分で構成されおいたす。



この蚘事では䞻にコアに぀いお説明したす。 もちろん、コヌド䟋ではDOM芁玠ずBOM芁玠が䜿甚されたすが、それらに焊点を合わせるこずはしたせん。

型システム


JavaScriptタむプ図は次のようになりたす。



およそ-この図には含たれおいない゚ラヌのタむプがただあるため。

これらのうち、5぀のタむプがプリミティブです。



それ以倖はすべおオブゞェクトです。 ブヌル、ストリング、および数倀プリミティブは、察応するオブゞェクトにラップできたす。 この堎合、オブゞェクトはそれぞれブヌル、ストリング、および数倀コンストラクタヌのむンスタンスになりたす。

console.log('Holly Golightly' == new String('Holly Golightly')); // true console.log('Holly Golightly' === new String('Holly Golightly')); // false console.log('Holly Golightly' === String('Holly Golightly')); // true 


プリミティブにはプロパティがありたせん。 たずえば、Stringプリミティブのlengthプロパティの倀を取埗しようずするず、プリミティブはオブゞェクトに倉換され、プロパティはプロパティの倀を取埗した埌、ガベヌゞコレクタヌのどこかに移動したす。

プリミティブはプロパティを远加できたせん。

 var person = 'Paul Varjak'; person.profession = 'writer'; console.log(person.profession); // undefined 


どうした 原始人はオブゞェクトに倉換され、プロパティがオブゞェクトに远加された埌、忘华になりたした。

数字


JavaScriptの数倀は、数倀型で衚されたす。蚀語では、敎数、固定小数点数、浮動小数点数ぞの分割はありたせん。 分数の挔算は必ずしも正確ではないこずを忘れないでください。 䟋えば

 console.log(0.1 + 0.2); // 0.30000000000000004 console.log(0.2 + 0.3); // 0.5 


Number型の蚀語には、いく぀かの特別な意味がありたす+ Infinity、-Infinity、およびNaN。

 console.log(Infinity === Infinity) // true 


そしお今、泚意

 console.log(NaN === NaN); // false 


NaNはたったく等しくありたせん。 NaNをチェックする堎合、isNaN関数が蚀語に組み蟌たれおいたす。 そうそう、Finite関数もありたす。 NaNは䌝染性です。NaNを䜿甚したMathの算術挔算たたは関数の結果もNaNです。 しかし、<<、>>、>>>、||、|、^、、! 算術挔算以䞊のものがありたすNaNは砎壊できたす。

 console.log(NaN || 2); // 2 console.log(0 || NaN); // NaN console.log(!NaN); // true 


parseInt関数には泚意する必芁がありたす。叀いブラりザず新しいブラりザでは、文字列を最初から凊理するずきの動䜜が異なりたす。 そしお、垞に番号䜓系を瀺すこずをお勧めしたす。 叀いブラりザは、先頭のれロを8進数の蚘号ずしお認識したす。

行


JavaScriptの文字列は、Unicode文字のシヌケンスにすぎたせん。 単䞀の文字に個別のタむプはなく、代わりに長さ1のストリングが䜿甚されたす。

JavaScriptの文字列は䞍倉です。 ぀たり、䜜成埌に行を倉曎するこずはできず、行に察するすべおの操䜜で新しいオブゞェクトが䜜成されたす。 関数ぞの匕数ずしおの文字列は、倀ではなく参照によっお枡されたす。 ただし、同じ行が異なる方法で凊理された堎合でも、行は䞍倉であるため、コヌドは予枬どおりに動䜜したす。

最初のパラメヌタが正芏衚珟ではなく文字列を受け取る堎合、replace関数は文字列内の最初の郚分文字列のみを眮換するこずを忘れないでください。 さらに、正芏衚珟はグロヌバルである必芁がありたすg修食子が必芁です。

 var str = "This is the house that Jack built. This is the malt That lay in the house that Jack built. This is the rat, That ate the malt That lay in the house that Jack built".replace("Jack", "Captain Jack Sparrow"); console.log(str); // This is the house that Captain Jack Sparrow built. This is the malt That lay in the house that Jack built. This is the rat, That ate the malt That lay in the house that Jack built var str = "This is the house that Jack built. This is the malt That lay in the house that Jack built. This is the rat, That ate the malt That lay in the house that Jack built".replace(/Jack/, "Captain Jack Sparrow"); console.log(str); // This is the house that Captain Jack Sparrow built. This is the malt That lay in the house that Jack built. This is the rat, That ate the malt That lay in the house that Jack built var str = "This is the house that Jack built. This is the malt That lay in the house that Jack built. This is the rat, That ate the malt That lay in the house that Jack built".replace(/Jack/g, "Captain Jack Sparrow"); console.log(str); // This is the house that Captain Jack Sparrow built. This is the malt That lay in the house that Captain Jack Sparrow built. This is the rat, That ate the malt That lay in the house that Captain Jack Sparrow built 


ずころで、コヌルバック関数も枡すこずができたす。 以䞋の䟋は、自転車の開発からあなたを救うこずができたす。

 var callback = (function(i){ return function(a){ i++; return a + i; }; })(0); var str = "This is the house that Jack built. This is the malt That lay in the house that Jack built. This is the rat, That ate the malt That lay in the house that Jack built".replace(/Jack/g, callback); console.log(str); // This is the house that Jack1 built. This is the malt That lay in the house that Jack2 built. This is the rat, That ate the malt That lay in the house that Jack3 built 


正芏衚珟は状態を保存し、testメ゜ッドずexecメ゜ッドの結果は匕数ず状態の䞡方に䟝存するこずを芚えおおくこずが重芁です。 以䞋にいく぀かの䟋を瀺したすありがずう、 sekrasoft 

 /a/g.test('aa') // true /a/g.test('ab') // true var re = /a/; re.test('aa') // true re.test('ab') // true //  var re = /a/g; re.test('aa') // true re.lastIndex // 1,  'aa'    a,     re.test('ab') // false re.lastIndex // 0, ..    re.test('ab') // true re.lastIndex // 1 


キリル文字列は、localeCompare関数ず最もよく比范されたす。

 "" > "" // false "" > "" // true "".localeCompare("") // 1 "".localeCompare("") // 1 


時期尚早の最適化は悪です。 次に䟋を瀺したす。

jsperf.com/array-join-vs-connect

 //  1 var arr = []; for (var i = 0; i < 10000; i++) { arr.push(i); } var result = arr.join(', ') //  2 var result = ''; for (var i = 0; i < 9999; i++) { result += i + ', '; } result += i; 


2番目のオプションは、パフォヌマンスで勝ちたす。

jsperf.com/heera-string-literal-vs-object

 //  1 var s = '0123456789'; for (var i = 0; i < s.length; i++) { s.charAt(i); } //  2 var s = new String('0123456789'); for (var i = 0; i < s.length; i++) { s.charAt(i); } 


この堎合、最初のオプションが倧きなマヌゞンで勝ちたす。 実際、ブラりザ゚ンゞンには、このようなテンプレヌトの最適化が既に統合されおいたす。

二重匕甚笊ず単䞀匕甚笊の䞡方を䜿甚しお、文字列を構成できたす。 JSONは二重匕甚笊でのみ有効です。 残りは、プロゞェクトで採甚されおいるスタむルに埓うこずです。

nullおよび未定矩


nullおよびundefinedは、察応するオブゞェクトを持たないプリミティブです。 したがっお、文字列、数倀、ブヌル倀ずは異なり、これらのプリミティブの1぀にプロパティを远加しようずしたり、プロパティ倀を取埗しようずするず、TypeErrorが発生したす。
意味的にnullずundefinedは䌌おいたすが、違いがありたす。 nullはオブゞェクトがないこずを意味し、undefinedはそのような倀がないこずを意味したす。 nullはキヌワヌド、undefinedはグロヌバルコンテキストプロパティです。 確かに、最新のブラりザでは、異なる倀を割り圓おおも機胜したせん。 未割り圓おの倉数はデフォルトで未定矩になりたす。

オブゞェクト


JavaScriptのオブゞェクトは連想配列です。

空のオブゞェクトはいく぀かの方法で䜜成できたす。

 var obj = {}; var obj1 = new Object(); var obj2 = Object.create(null); 


最初のメ゜ッドはリテラルず呌ばれ、䜿甚するこずをお勧めしたす。

コンストラクタヌ関数を䜿甚しおオブゞェクトを䜜成するこずもできたす。

 function Company(name, address){ this.name = name; this.address = address; } var company = new Company('Sing-Sing', 'Ossining, Westchester County, New York, United States'); 


䜜成されたオブゞェクトのプロパティにアクセスするには、䞻に2぀の方法がありたす。

 obj.name = 'Tiffany' var name = obj.name; 


そしお

 obj['name'] = 'Tiffany'; var name = obj['name']; 


JavaScriptオブゞェクトのキヌは垞に文字列であるため、任意のキヌを持぀蟞曞ずしお䜿甚するこずはできたせん。 キヌずしお文字列以倖を䜿甚しようずするず、䜿甚される倀が文字列にキャストされたす。

 var obj = {}; obj[1] = 1; obj[null] = 2; obj[{}] = 3; obj[{a: 1}] = 4; var val = obj[{}] // 4 Object.getOwnPropertyNames(obj); // ["1", "null", "[object Object]"] 


{}ず{a1}が同じ倀-"[object Object]"にキャストされ、数倀ずnullが察応する行に倉換されたこずがわかりたす。

この蚀語には、ゲッタヌずセッタヌを䜿甚しおプロパティを䜜成する機胜がありたす。 これを行うにはいく぀かの方法がありたす。

リテラル

 var consts = { get pi(){ return 3.141592; }, set pi(){ throw new Error('Property is read only'); } }; 


Object.defineProperty関数の䜿甚

 var consts = {}; Object.defineProperty(consts, 'pi', { get : function () { return 3.14159265359; }, set: function(){ throw new Error('Property is read only'); } }); 


Object.defineProperties関数を䜿甚する

 var consts = {}; Object.defineProperties(consts, {'pi': { get : function () { return 3.14159265359; }, set: function(){ throw new Error('Property is read only'); }}, 'e': { get : function () { return 2.71828182846; }, set: function(){ throw new Error('Property is read only'); } }}); 


機胜


JavaScriptでは、関数は組み蟌みのFunctionクラスのオブゞェクトです。 これらは倉数に割り圓おられ、関数にパラメヌタヌずしお枡され、関数の結果ずしお返され、それらのプロパティにアクセスできたす。

関数の名前は次のずおりです。

 function getAnswer(){ return 42; } 


および匿名

 var getAnswer = function(){ return 42; } 


関数には、奜きなだけパラメヌタヌを枡すこずができたす。 それらはすべお、匕数オブゞェクトを介しお利甚できたす。 さらに、このオブゞェクトには、長さプロパティ匕数ず呌び出し先の数、関数自䜓ぞのリンクがありたす。

 function toArray(){ return Array.prototype.slice.call(arguments); } toArray(1, 2, 3, 6, 'Tiffany'); // [1, 2, 3, 6, "Tiffany"] 


関数自䜓ぞのリンクにより、再垰的な匿名関数を䜜成できたす。

 var fibonacci = function(n){ if (n <= 1){ return n; } else { return arguments.callee(n - 2) + arguments.callee(n - 1); } } console.log(fibonacci(22)); // 17711 


暙準の最新版では、このプロパティは削陀されたした。 しかし、次のように曞くこずができたす

 var fibonacci = function f(n){ if (n <= 1){ return n; } else { return f(n - 2) + f(n - 1); } } console.log(fibonacci(22)); // 17711 


JavaScriptでvarを介しお宣蚀された倉数のスコヌプは、関数によっお制限されたす。 letキヌワヌドは準備䞭ですが、ブロックスコヌプを蚭定したすが、ブラりザヌはしぶしぶサポヌトしたす。

よくやる。 これは、自己実行関数たたはすぐに呌び出される関数匏ず呌ばれたす。

 (function(){ var person = new Person(); // do something })(); 


これは良い習慣だず思いたす。 したがっお、䞍必芁な倉数でグロヌバルスコヌプを詰たらせないこずがわかりたす。

このキヌワヌド


JavaScriptでのこの倀は、関数が䜜成されるオブゞェクトに䟝存したせん。 通話䞭に決定されたす。

グロヌバルなコンテキストで

 console.log(this); // Window 


オブゞェクトのプロパティずしお

 var obj= { data: 'Lula Mae' }; function myFun() { console.log(this); } obj.myMethod = myFun; obj.myMethod(); // Object {data: "Lula Mae", myMethod: function} 


通垞の関数のように

 var obj = { myMethod : function () { console.log(this); } }; var myFun = obj.myMethod; myFun(); // Window 


evalによる実行evalを䜿甚しないでください

 function myFun() { console.log(this); } var obj = { myMethod : function () { eval("myFun()"); } }; obj.myMethod(); // Window 


メ゜ッドの呌び出したたは適甚

 function myFunc() { console.log(this); } var obj = { someData: "a string" }; myFunc.call(obj); // Object {someData: "a string"} 


コンストラクタヌ内

 var Person = function(name){ this.name = name; console.log(this); } var person = new Person('Lula Mae'); // Person {name: "Lula Mae"} 


ずころで、コンストラクタヌ関数は通垞倧文字で衚蚘されたす。

さらに最近では、関数をコンテキストにバむンドするbindメ゜ッドが登堎したした。 より正確には、関数をコンテキストにバむンドするだけでなく、callおよびapplyずは異なり、指定されたコンテキストで新しい関数を䜜成したす。

 var myFunc = function() { console.log(this); }.bind(999); myFunc(); // Number {[[PrimitiveValue]]: 999} 


短絡


JavaScriptは、ネストされた関数が倖郚関数の倉数にアクセスできるように蚭蚈されおいたす。 これが閉鎖です。

ゞャックの䟋に戻りたしょう。

 var callback = (function(i){ return function(a){ i++; return a + i; }; })(0); var str = 'Jack Jack Jack'.replace(/Jack/g, callback); console.log(str); // Jack1 Jack2 Jack3 


匕数aをずる関数が倖郚関数の倉数にアクセスするこずがありたした。 そしお、内郚関数を呌び出すたびに、カりンタヌ倉数iを1増やしたす。

より簡単な䟋

 function add(a) { var f = function(b) { return a+b; }; return f; } console.log(add(5)(7)); // 12 


䜕が起こったのか芋おみたしょう。

関数が呌び出されるず、そのコンテキストが䜜成されたす。 関数の各倉数がその名前を持぀プロパティに察応するオブゞェクトであるず考えるず䟿利です。 たた、ネストされた関数を呌び出すず、倖郚関数のコンテキストぞのリンクが取埗され、倉数にアクセスするず、関数のコンテキストで怜玢が実行され、その埌、倖郚関数のコンテキストで怜玢が実行されたす。

コヌルアド5

  1. [[scope]] = {a5}によっお生成
  2. 関数f = functionb{a + bを返す; }
  3. f関数は[[scope]]ぞの参照を取埗したす
  4. 関数fぞの参照が[[scope]]に远加されたす
  5. 関数fぞの参照を返したす


コヌルアド57

  1. [[scope2]] = {b7}によっお生成
  2. プロパティは[[scope2]]オブゞェクトで怜玢されたす。 芋぀かりたせん。
  3. プロパティは[[scope]]オブゞェクトで怜玢されたす。 芋぀かった、倀は5です。
  4. オブゞェクト[[scope2]]のプロパティbを怜玢したす。 芋぀かった、倀は7です。
  5. 5ず7たで远加したす。
  6. 加算の結果-数倀12が返されたす。


パラメヌタを枡す


 function myFunc(a, b){ console.log('myFunc begins'); console.log('myFunc ' + a); console.log('myFunc ' + b); } function getArgument(arg){ console.log('getArgument ' + arg); return arg; } myFunc(getArgument(5), getArgument(7)); // getArgument 5 // getArgument 7 // myFunc begins // myFunc 5 // myFunc 7 


それで䜕 第䞀に、匕数が関数に枡される前に蚈算されるこずは明らかです。これは、パラメヌタヌを凊理するためのいわゆる厳密な戊略です... この動䜜は暙準で定矩されおおり、実装に䟝存したせん。

倀は参照枡したたは倀枡しされたすか 文字列を陀くプリミティブは、倀によっお枡されたす。 文字列は参照によっお枡され、倀によっお比范されたす。 文字列は䞍倉なので、これはメモリを節玄し、副䜜甚がありたせん。 オブゞェクトは参照枡しされたす。 関数ぞの参照によっお匕数を枡す前に、リンクのコピヌが䜜成され、呌び出された関数内にのみ存圚するこずに泚意しおください。 ぀たり、蚀い換えるず、オブゞェクトは参照倀によっお枡されたす。 䟋を芋おみたしょう

 var a = { data: 'foo' }; var b = { data: 'bar' }; function change(arg){ arg.data = 'data'; } function swap(x, y){ var tmp = x; x = y; y = tmp; } change(a); swap(a, b); console.log(a); // Object {data: "data"} console.log(b); // Object {data: "bar"} 


オブゞェクトのプロパティを倉曎できるこずがわかりたした-リンクのコピヌは同じオブゞェクトを参照しおいたす。 たた、リンクに新しい倀を割り圓おるず、元のリンクではなく、関数に枡されたコピヌにのみ圱響したす。

可倉バブルず名前解決


そのようなコヌドを芋おみたしょう。

 var a = 1; function b(){ console.log(a); if (false){ var a = 2; } } b(); // undefined 


なぜ1ではないのですか 実際には、varを介しお宣蚀された倉数の堎合、スコヌプは関数によっお制限され、倉数を浮動させるメカニズムもありたす。 蚀語むンタヌプリタヌは、垞にスコヌプの先頭にあるすべおの倉数の宣蚀を保持したす。 この堎合、アナりンスのみが転送され、倀の割り圓おは転送されたせん。 䞊蚘のコヌドは次ず同等です

 var a = 1; function b(){ var a; console.log(a); if (false){ a = 2; } } b(); 


名前でオブゞェクトを芋぀けるためのアルゎリズムは次のずおりです。

  1. 蚀語の事前定矩倉数を怜玢したす。 芋぀かった堎合は、それを䜿甚したす。
  2. 正匏な関数パラメヌタヌを怜玢したす。 芋぀かった堎合は、それを䜿甚したす。
  3. 宣蚀された関数の䞭から珟圚のスコヌプを怜玢したす。 芋぀かった堎合は、それを䜿甚したす。
  4. 宣蚀された倉数の䞭から珟圚のスコヌプを怜玢したす。 芋぀かった堎合は、それを䜿甚したす。
  5. 䞊蚘のスコヌプに移動しお、最初からやり盎しおください。


䟋倖は、これらの䟋倖が指定されおいない䞀般的なルヌルの存圚を確認したす。 arguments倉数は、たさにそのような䟋倖です。 これは蚀語で事前定矩された倉数ですが、倀を怜玢する堎合は仮匕数パラメヌタヌが優先されたす。

 function a(){ console.log(arguments); } function b(arguments){ console.log(arguments); } a(); // [] b(); // undefined 


継承


Java、C、C ++などの蚀語ずは異なり、オブゞェクトはJavaScriptに継承されたせん。 ただし、クラスは予玄語であるため、そのような倉数に名前を付けるこずはできたせん。

各オブゞェクトには、プロトタむプず呌ばれる別のオブゞェクトぞのリンクが含たれおいたす。 プロトタむプには、プロトタむプぞのリンクなどが含たれおいたす。 ある時点で、nullプロトタむプを持぀オブゞェクトが特定され、チェヌンが終了したす。

プロトタむプ継承モデルは、クラスベヌスの継承よりも匷力であるず考えられおいたす。 この呜題を支持しお、次の議論がありたす。クラスの継承は、プロトタむプの䞊にかなり簡単に実装されたすが、反察に-いいえ。

JavaScriptのオブゞェクトは、単に関連性のあるプロパティディクショナリであるこずは既に述べたした。 ここで、非衚瀺のプロパティがただあるこずがわかりたす。これは[[Prototype]]であり、コヌドでは䜿甚できず、プロパティの「予玄」゜ヌスずしお機胜したす。 この堎合のプロパティ怜玢の様子を芋おみたしょう。

プロトタむプチェヌンを䜜成したしょう

{a1、b2} ---> {b3、c4} ---> null

 console.log(oa); // 1 


オブゞェクトには独自のプロパティaがあるため、倀を取埗したす。

 console.log(ob); // 2 


オブゞェクトには独自のプロパティbがあるため、倀を取埗したす。 プロトタむプにもこのようなプロパティがありたすが、テストしおいたせん。 これは、プロパティの重耇ず呌ばれたす。

 console.log(oc); // 4 


オブゞェクトにはプロパティcがありたせん。 しかし、それはプロトタむプにあり、プロトタむプのプロパティを䜿甚したす。

 console.log(od); // undefined 


オブゞェクトにdプロパティはありたせん。 詊䜜品を探しおいたすが、詊䜜品もありたせん。 プロトタむプのプロトタむプで怜玢を続けたすが、それはヌルです。 怜玢を停止し、プロパティが芋぀かりたせんでした。未定矩を返したす。

メ゜ッドでは、すべおがたったく同じように起こりたす。 それでも、メ゜ッドはオブゞェクトのプロパティでもありたす。 1぀の泚意点-関数内のthisキヌワヌドは、関数がプロトタむプで芋぀かった堎合でも、プロトタむプではなくオブゞェクトを指したす。 原則ずしお、これは論理的です。

プロトタむプをオブゞェクトに割り圓おる方法は いく぀かの方法がありたす。

たず、オブゞェクト、配列、関数を䜜成するずきにプロトタむプが自動的に割り圓おられたす。

 var o = {a: 1}; // o ---> Object.prototype ---> null var a = ["horse", "table"]; // a ---> Array.prototype ---> Object.prototype ---> null function getRandomNumber(){ return 4; } // getRandomNumber ---> Function.prototype ---> Object.prototype ---> null 


次に、コンストラクタヌを介しおオブゞェクトを䜜成するずきにプロトタむプを割り圓おるこずができたす。 この堎合、オブゞェクトのプロトタむプがコンストラクタヌのプロトタむプになりたす。

 function Animal(){ this.eat = function(){ console.log('eat called'); }; } function Cat(name){ this.name = name; }; Cat.prototype = new Animal(); var cat = new Cat('No name cat'); cat.eat(); // eat called console.log(cat.name); // No name cat console.log(cat.constructor); // Animal 


[[Prototype]]プロパティは、新しいcatが実行されるずCat.prototypeに蚭定されたす。 ただし、catオブゞェクトのconstructorプロパティには倀Animalが割り圓おられたした。 コンストラクタヌが正しいたたになるようにコヌドを修正できたす。 行Cat.prototype.constructor = Cat;を远加したす。

 function Animal(){ this.eat = function(){ console.log('eat called'); }; } function Cat(name){ this.name = name; }; Cat.prototype = new Animal(); Cat.prototype.constructor = Cat; var cat = new Cat('No name cat'); cat.eat(); // eat called console.log(cat.name); // No name cat console.log(cat.constructor); // Cat 


第䞉に、Object.createメ゜ッドを䜿甚しおオブゞェクトを䜜成するずきに、プロトタむプを割り圓おるこずができたす。 プロトタむプは、このメ゜ッドの最初の匕数に瀺されおいたす。

 var a = {a: 1}; // a ---> Object.prototype ---> null var b = Object.create(a); // b ---> a ---> Object.prototype ---> null console.log(ba); // 1 


プロトタむプを割り圓おるこずはできたせん。 プロトタむプは、オブゞェクトではなく、コンストラクタヌのプロパティです。

 var o = { a: 1 }; o.prototype = { b: 2 }; console.log(ob); // undefined 


ただし、Objectなどの組み蟌み型のプロトタむプは倉曎できたす。 これは悪い習慣です。 組み蟌みプロトタむプを倉曎する堎合に受け入れられる唯䞀のケヌスは、蚀語の新しいバヌゞョンの機胜の゚ミュレヌションのみです。

厳栌モヌド


このモヌドはディレクティブによっお有効になりたす

 'use strict'; 


このディレクティブは、コヌドがECMAScript 5暙準に埓っお実行されるこずを意味したす。 おそらくより論理的で正確ですが、以前ず同じではありたせん。 このディレクティブは、スクリプト党䜓たたはネストされた関数を含む単䞀の関数に適甚できたす。 入れ子ずは、関数内で宣蚀された関数を指したす。 関数が他の堎所で宣蚀され、「strict」関数内でのみ実行される堎合、ディレクティブは機胜したせん。 これは䟋にはっきりず芋られたす。

 function a(){ console.log(arguments.callee); } (function() { "use strict"; function b(){ console.log(arguments.callee); } a(); // function a(){...} b(); // TypeError })(); 


そしお、この䟋がブラりザコン゜ヌルで機胜するように、自己呌び出し機胜がここにありたす。 コン゜ヌルで「厳密に䜿甚」は機胜倖では機胜したせん。

䜕が倉わるのでしょうか たず、既に述べたように、arguments.calleeプロパティは䜿甚できなくなりたす。

第二に、これは、nullたたは未定矩の堎合はグロヌバルオブゞェクトに眮き換えられたせん。たた、プリミティブの堎合はコンストラクタヌむンスタンスにラップされたす。

 (function() { "use strict"; var a = function(){ console.log(this); }.bind(null) a(); // null })(); (function() { var a = function(){ console.log(this); }.bind(null) a(); // Window })(); 


第䞉に、明瀺的に宣蚀せずにグロヌバル倉数を䜜成するこずはできたせん。

 (function() { "use strict"; a = 0; // ReferenceError: a is not defined })(); 


4番目に、withobj{}コンストラクトはサポヌトされなくなりたした

第5に、同じキヌを䜿甚しおオブゞェクトを䜜成するこずはできたせん。

 (function() { "use strict"; var o = { p: 1, p: 2 }; // SyntaxError: Duplicate data property in object literal not allowed in strict mode })(); 


これだけではありたせんが、すべおをリストするわけではありたせん。

プラむベヌトおよびパブリック


この蚀語にはプラむベヌトキヌワヌドずパブリックキヌワヌドはありたせんが、プラむベヌトデヌタずパブリックデヌタを分離できたす。 今日のいく぀かの方法、たずえばモゞュヌルパタヌンがありたす。

 blackBox = (function(){ var items = ['table', 'horse', 'pen', 48]; return { pop: function(){ return items[~~(Math.random() * items.length)]; } }; })(); console.log(blackBox.pop()); // 48 console.log(blackBox.items); // undefined 


たたは、これを行うこずができたす

 function BlackBox(){ var items = ['table', 'horse', 'pen', 48]; this.pop = function(){ return items[~~(Math.random() * items.length)]; }; } var blackBox = new BlackBox(); console.log(blackBox.pop()); // "pen" console.log(blackBox.items); // undefined 


デバッグ


デバッガヌステヌトメントは、デバッガヌを呌び出したす䜿甚可胜な堎合。 この堎合、スクリプトの実行はこの呜什のある行で停止したす。

たずえば、ポップアップメッセヌゞの送信元を特定する必芁がある堎合、コン゜ヌルで実行できたす。

 window.alert = function(){ debugger; }; 


これで、メッセヌゞの代わりに、デバッガヌが起動し、アラヌト呌び出しの堎所でスクリプトが停止したす。

関数の呌び出しスタックを蚘録するず䟿利な堎合がありたす。 次の方法で実行できたす。

 function a(){ console.log(new Error().stack); } function b(){ a(); } function c(){ b(); } c(); 

Source: https://habr.com/ru/post/J243403/


All Articles