在JavaScript中~[]构造是如何工作的?
我遇到了一个无法解释的JavaScript代码。 例如:在JavaScript中~[]构造是如何工作的?,javascript,brackets,tilde,Javascript,Brackets,Tilde,我遇到了一个无法解释的JavaScript代码。 例如: +[]==0 -[]==0 ~[]==-1 ~-~[]==-2 ~-~-~-~[]==-5 ~-~-~-~[]+~[]==-6 ~+~[]==0 ~+~+~[]==-1 ~+~+~+~[]==0 您能解释一下这些表达式的逻辑吗?[]是一个空数组对象,因此: +[]:强制空数组为正整数,也称为0,即===到0 -[]:强制空数组为负整数,也称为0,即===到0 ~[]:按位非空数组,其计算结果为-1,即===到-1 ~-~[]:按位NO
+[]==0
-[]==0
~[]==-1
~-~[]==-2
~-~-~-~[]==-5
~-~-~-~[]+~[]==-6
~+~[]==0
~+~+~[]==-1
~+~+~+~[]==0
您能解释一下这些表达式的逻辑吗?
[]
是一个空数组对象,因此:
+[]:强制空数组为正整数,也称为0,即===到0-[]:强制空数组为负整数,也称为0,即===到0
~[]:按位非空数组,其计算结果为-1,即===到-1
~-~[]:按位NOT的求反NOTted空数组:
~-(-1)->~1->-2
等等。当您对任何内容使用
+
或-
运算符时,它会调用其上的数字Number([])
返回0
,因此您可以得到前两个答案
~
运算符不是按位的。基本上,它将一个数字中的所有位反转,从而将0
更改为-1
。更多关于位运算符的信息
其余的只是这些案例的组合。你几乎可以把这些东西组合成你想要的任何数字。我相信,如果我错了,请纠正我,但是添加到数组(例如,向数组中添加值而不是向数组中添加值)会将其转换为数字。其余的只是使用基本+,-运算符(波浪号(~)是一个按位NOT)修改数字,然后修改一个方程
So [] == array ([]);
[] + 1 == number (0);
+[]===0 (true)
我会尽力而为:
[]==0
当然是错误的,因为[]
并不完全等于0。但是,[]==0
为真,因为存在隐式强制转换
+
和-[]
之所以有效,是因为加号或减号将[]
转换为实数
~0
(0的位逆)是-1。因此,~[]=-1
起作用
其他方法只是通过多次减去或加-1来工作。我将尝试描述为什么会得到这个结果,而不是重复您在问题中演示的结果
解释
仅以第一个示例为例(因为其他示例将执行类似的操作),我们可以按照规范来查看发生了什么
从中,我们可以看到发生了ToNumber
转换
返回ToNumber(GetValue(expr))
从中我们可以看到,如果给定一个对象(如数组),则会进行ToPrimitive
转换,然后再次尝试ToNumber
对象
应用以下步骤:
让PrimitValue为TopPrimitive(输入参数、提示号)
返回tonNumber(primValue)
从中,如果ToPrimitive
获取一个对象,我们可以看到它的[[DefaultValue]]]
被获取:
对象
返回对象的默认值。通过调用对象的[[DefaultValue]]内部方法并传递可选提示PreferredType,可以检索对象的默认值。[[DefaultValue]]内部方法的行为由本规范为8.12.8中的所有本机ECMAScript对象定义
从中,最终将对数组调用并返回toString()
。如上所述,此字符串被发送到递归的ToNumber
那么当对字符串进行ToNumber
转换时会发生什么呢?嗯,这是在中描述的,有点长。更简单的方法是直接进行转换,看看会发生什么:
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
结果。
显示更多的<代码> toStase数组的转换,请考虑以下内容:
[1].toString(); // "1"
[1,2,3].toString(); // "1,2,3"
["a",1,"b",2].toString(); // "a,1,b,2"
因此,要对上述数组进行ToNumber
转换,第一个数组将给出一个数字,最后两个数组将得到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;
};
所以现在你可以看到我们的数组的ToNumber
转换以前会产生NaN
,现在会产生数组中项目的总和。如果我遇到这样的代码,我想我会翻桌子。答案是:+[NaN]==!!!!0&&+[{}]+~~[[]]-[]
如果我在任何代码库中看到这一点,我会要求原始开发人员重写它。这是非常糟糕的练习!!!这些是JavaScript的宝剑。使用它们来获得最大的公正。事实上,它将其转换为一个字符串,而不是一个数字[1]+1=“11”
所以+[]=0
因为这就像做+”
应该是:~1->-2
在最后一个字符串-1+[]:强制空数组为正整数,也就是0,这并不能解释为什么会发生这种情况。它只是重申了结果。显然,如果+[]==0
,则+[]
必须已转换为0
。这个问题要求解释逻辑,明白了。我错过了[]
到0
部分的演员阵容。
Number([1,2,3]); // 6
+[1,2,3]; // 6