この記事の例では、JavaScript 配列での Push メソッドの使用法について説明します。参考のために皆さんと共有してください。詳細は次のとおりです:
以下のコードを見てください:
var o = { 1:'a' ,2:'b' ,length:2 ,push:Array.prototype.push }; o.push('c');
Q:o 内部値は今どうなっていますか?
私の最初の反応は拒絶でした。なぜ不合理な状況下で [説明エンジン] の動作を研究する必要があるのでしょうか?しかし、この種の推論は非常に魅力的な場合もあるので、戻ってよく考えてみると、実際には非常に単純であることがわかりました。
プッシュメソッドについて、私が反射的に思い浮かべるのはスタックです。 [データ構造の古典的なスタック] プッシュおよびポップ操作はスタックの先頭ポインタに基づいており、先頭ポインタは常にスタックの先頭を指します。つまり、スタックを下げると自動的に増加または減少します。 JavaScript の配列では、このポインターは長さになります。したがって、上記のコードでは、o.push('c') は o.2 = 'c' です (もちろん、o.2 に直接アクセスすることはできません。これは単なる疑似コードです)。そのため、コードが実行された後の o のデータは次のようになります。
{ 1:'a' ,2:'c' ,length:3 //push操作=>length+1 ,push:Array.prototype.push }
追加説明:
JavaScript ではすべてがオブジェクトであり、JavaScript オブジェクトは厳密に型指定されたオブジェクトとは多少異なります。実績はキーと値のペアのコレクションであることが理解できます。 。配列型も例外ではなく、その添え字アクセスはキー アクセスです (ただし、そのキーはすべて自然数です)。上記の例では、 に割り当てられたオブジェクト リテラルは実際には配列 (1 つの配列から始まる添え字) をシミュレートします。配列にはいくつかの特性しかありません。たとえば、実際の配列がキーによってアクセスされると、長さに基づいて範囲外チェックが実行されます。
押す位置が長さに基づいていることを知っていれば、次の一見奇妙な現象は簡単に理解できます:
//1.length不存在,引擎置为0 var o = { '1':'a' ,'2':'b' ,push:Array.prototype.push }; o.push('c');//c {0:'c',1:'a',2:'b',...} //2.length为负值,这是个有趣的问题,涉及到原码反码和补码【1】 var o = { '1':'a' ,'2':'b' ,length:-1 ,push:Array.prototype.push }; o.push('c');//c {1:'a',2:'b',4294967295:'c',length:4294967296,...} //3.length为字符或对象 var o = { 1:'a' ,2:'b' ,length:'A' ,push:Array.prototype.push }; o.push('c');//c {0:'c',1:'a',2:'b',length:1,...}我还以为js解释器会把A转换成ASCII码来给length赋值呢,终于看到了javascript的自由还是有节操的
コンピューター内の数値は、計算を容易にするために 2 の補数形式で保存されます。 1 の補数は 4294967295 の補数と同じです。長さのセマンティクスによれば、符号なしの数値
[-1] 補数 = 1111 1111 1111 1111 1111 1111 1111 1111 = [4294967295] 補数 = 1111 1111 11 1111 1 111 1111 1111 1111
このようにして、差分ペア 2 の o を接続し、オブジェクトにプッシュします。ただし、配列の最大長は 4294967296 に制限されています。つまり、添字は 4294967296 に制限されています。 get 4294967295、および 32 ビットのみ - —4294967296 = 1 0000 0000 0000 0000 0000 0000 0000 0000 の場合、最後の 32 ビットは 0 になるため、このプッシュの位置は 0 になります。