説明できないJavaScriptコードが出てきました。例えば :〜[]構築はどのようにJavaScriptで動作しますか?
+[]===0
-[]===0
~[]===-1
~-~[]===-2
~-~-~-~-~[]===-5
~-~-~-~-~[]+~[]===-6
~+~[]===0
~+~+~[]===-1
~+~+~+~[]===0
あなたは、これらの式のロジックを説明できますか?
+ []:
説明できないJavaScriptコードが出てきました。例えば :〜[]構築はどのようにJavaScriptで動作しますか?
+[]===0
-[]===0
~[]===-1
~-~[]===-2
~-~-~-~-~[]===-5
~-~-~-~-~[]+~[]===-6
~+~[]===0
~+~+~[]===-1
~+~+~+~[]===0
あなたは、これらの式のロジックを説明できますか?
+ []:
[]
ので、空の配列オブジェクトである力空の配列は0
に===は正の整数、別名0であるように[ - ]:力空の配列になるように負の整数、別名0 = 0から0まで
〜[]:-1で-1と評価されるビット単位でない空の配列
〜〜[]:否定のビット単位NOT空の配列NOTFT:~-(-1) -> ~1 -> -2
など...
は、最後の文字列の '〜1 - > -2'にする必要があります。 – Denis
ありがとう、答えを修正しました。 –
-1 '+ []:空の配列を強制的に正の整数にする、別名0、===〜0'はなぜそれが起こるのか説明しません。それは単に結果を再表示します。明らかに '+ [] === 0'なら、' + [] 'は' 0'に変換されていなければなりません。質問は論理を説明するよう求めます。 – RightSaidFred
私が間違っていると私は正しいと思っていますが、配列に値を追加するのではなく、値を配列に追加すると、数値にキャストされます。残りの部分は基本+、 - 演算子(チルダ(〜)はビット単位でNOT)を使用して数を変更してから方程式を修正します。
So [] == array ([]);
[] + 1 == number (0);
+[]===0 (true)
実際には数値ではなく文字列にキャストします。 '[1] + 1 =" 11 "' so '+ [] = 0'は' + " – pleasedontbelong
私は自分のベストを尽くします:暗黙のキャストが存在するため
[]===0
は、偽のはもちろんである[]
しかし0に正確に等しいではないので、[]==0
は本当です。
+
および-[]
は、プラスまたはマイナスキャスト[]
を実数にキャストします。
~0
(ビット反転が0)は-1です。したがって~[]===-1
が機能します。
他は、-1を複数回減算または加算するだけで動作します。
あなたが質問で示した結果を単に書き直す代わりに、私はなぜの結果を得るのかを説明しようとします。
説明
(残りは似たようなことを行いますので)最初の例に取ると、私たちは何が起こるかを見るために仕様に従うことができます。
11.4.6 Unary + Operatorから、ToNumber
の変換が行われることがわかります。
Return ToNumber(GetValue(expr))。私たちは(あなたのアレイのような)オブジェクトを指定した場合、
ToPrimitive
変換はToNumber
で別の試みに続いて行われていることがわかり9.3 ToNumberから
。
オブジェクトは、次の手順を適用します。
- がprimValueがたToPrimitive(入力引数、ヒント番号)とします。
- Return ToNumber(primValue)。
ToPrimitive
は、オブジェクトを取得する場合9.1 To Primitiveから
、我々はその[[DefaultValue]]
がフェッチであることがわかります。
オブジェクト
戻りオブジェクトのデフォルト値。オブジェクトのデフォルト値は、オプションのヒントPreferredTypeを渡して、オブジェクトの[[DefaultValue]]内部メソッドを呼び出すことによって取得されます。 [[DefaultValue]]内部メソッドの動作は、8.12.8のすべてのネイティブECMAScriptオブジェクトに対してこの仕様で定義されています。
8.12.8 [[DefaultValue]] (hint)から、最終的にはtoString()
が呼び出され、返されます。この文字列は上記のように再帰的なToNumber
に送られます。
したがって、文字列に対してToNumber
の変換が行われるとどうなりますか?それは9.3.1 ToNumber Applied to the String Typeに記載されていますが、少し長いです。 、何をすべきかの文字列我々はアレイから取り戻す
Number(""); // result is 0 on an empty string
Number(" "); // result is 0 on a string with only whitespace
Number("123"); // result is 123 on a numeric string
Number(" 123 ");// result is 123 on a numeric string with leading & trailing spaces
Number("abc"); // result is NaN (not a number) on non-numeric strings
そこで質問です:シンプルなだけで直接変換を行うには、何が起こるかを確認することです。繰り返しますが、これは簡単にテストするのは簡単です。
[].toString(); // result is "" (empty string)
結果が空の文字列であり、空の文字列のToNumber
変換我々は0 === 0
を比較している意味する上記のよう0
、あるので。
それは我々がやった場合と同じになります:
Number([].toString()) === 0; // true
それとももう少しそれを引き出す:
var x = [];
x = x.toString(); // ""
x = Number(x); // 0
x === 0; // true
もっとtoString
結果を。
[1].toString(); // "1"
[1,2,3].toString(); // "1,2,3"
["a",1,"b",2].toString(); // "a,1,b,2"
ので、上記アレイ上ToNumber
変換を行うために最初は私たちに番号を与えるだろう、最後の2つのことになる:、配列のよりtoString
変換を示し、次のことを考慮すること
NaN
。
Number([1]); // 1
Number([1,2,3]); // NaN
Number(["a",1,"b",2]); // NaN
いくつかの証拠
このtoString()
変換はToNumber
変換の前に起こる、我々は実際には異なる結果を提供するために、Array.prototype.toString
を変更することができ、かつ任意のToNumber
変換がそれを使用することをさらに証明を提供するために、変更された結果。ここで
Array.prototype.toString = function() {
var n = 0;
for(var i = 0; i < this.length; i++) {
n += this[i];
}
return n;
};
私は、Arrayを合計する機能をArray.prototype
にtoString
を交換しました。明らかにこれをやりたくはありませんが、私たちは今どのように違う結果が得られるかを示すことができます。
Number([1,2,3]); // 6
+[1,2,3]; // 6
だから今は、以前NaN
に生じるであろう私たちのアレイのToNumber
変換は今や配列内のアイテムの合計が生じていることがわかります。
私はそのようなコードに遭遇すれば私は机を裏返すだろうと思う。 –
答えは:+ [NaN] == !!!! 0 && + [{}] + ~~ [[]] - [] ' – jAndy
私はどのコードベースでも、元の開発者にリライトそれ。それはひどい練習です! –