javascript中对字符串的按位运算

tur*_*nvh 12 javascript binary

在javascript中,下面的字符到二进制操作的测试打印0676次:

var s = 'abcdefghijklmnopqrstuvwxyz';
var i, j;
for(i=0; i<s.length;i++){ for(j=0; j<s.length;j++){ console.log(s[i] | s[j]) }};
Run Code Online (Sandbox Code Playgroud)

如果js使用字符串的实际二进制表示,我希望这里有一些非零值.

类似地,测试字符串和整数的二进制操作,分别打印26 255秒和0s.(选择255是因为它是11111111二进制的).

var s = 'abcdefghijklmnopqrstuvwxyz';
var i; for(i=0; i<s.length;i++){ console.log(s[i] | 255) }
var i; for(i=0; i<s.length;i++){ console.log(s[i] & 255) }
Run Code Online (Sandbox Code Playgroud)

什么是javascript在这里做?似乎javascript false在二进制操作之前将任何字符串转换为.

笔记

如果你在python中尝试这个,它会抛出一个错误:

>>> s = 'abcdefghijklmnopqrstuvwxyz'
>>> [c1 | c2 for c2 in s for c1 in s]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for |: 'str' and 'str'
Run Code Online (Sandbox Code Playgroud)

但像这样的东西似乎在PHP中工作.

And*_*ark 11

在JavaScript中,当字符串与二元运算符一起使用时,它首先转换为数字.ECMAScript规范的相关部分如下所示,以解释其工作原理.

按位运算符:

生产A:A @ B,其中@是上述产品中的一个按位运算符,评估如下:

  1. 让lref成为评估A的结果.
  2. 设lval为GetValue(lref).
  3. 让rref成为评估B的结果.
  4. 设rval为GetValue(rref).
  5. 让lnum成为ToInt32(lval).
  6. 让rnum为ToInt32(rval).
  7. 返回将按位运算符@应用于lnum和rnum的结果.结果是带符号的32位整数.

ToInt32:

抽象操作ToInt32将其参数转换为-231到231-1范围内的2 个32个整数值之一(包括两者).这个抽象操作的功能如下:

  1. 设number是在输入参数上调用ToNumber的结果.
  2. 如果number为NaN,+ 0,-0,+∞或-∞,则返回+0.
  3. 让posInt为sign(number)*floor(abs(number)).
  4. 设int32bit为posInt modulo 2 32 ; 也就是说,具有正号并且幅度小于2 32的数字类型的有限整数值k 使得posInt和k的数学差异在数学上是2 32的整数倍.
  5. 如果int32bit大于或等于2 31,则返回int32bit - 2 32,否则返回int32bit.

内部ToNumber函数将为任何无法解析为数字的字符串返回NaN,而ToInt32(NaN)将给出0.因此在您的代码示例中,所有使用字母作为操作数的按位运算符将评估为0 | 0,这解释了为什么只有打印0.

请注意,类似的东西'7' | '8'会评估,7 | 8因为在这种情况下,用作操作数的字符串可以成功地被赋予一个数字.

至于为什么在Python行为是不同的,有没有真正在Python任何隐式类型转换,从而预期的错误任何类型的未实现二元运算(使用__or__,__and__等等),和字符串不实现那些二元运算符.

Perl完全不同,为字符串实现了按位运算符,它实际上将为每个字符串的相应字节执行按位运算符.

如果要使用JavaScript并获得与Perl相同的结果,则需要首先将字符转换为其代码点str.charCodeAt,对结果整数执行按位运算符,然后使用String.fromCodePoint将生成的数值转换为字符.


ale*_*lex 5

如果JavaScript可以对非数字字符串进行按位运算并产生有意义的结果,我会感到惊讶。我想像是因为JavaScript中的任何按位运算符都将其操作数转换为32位整数,所以它将简单地将所有非数字字符串转换为0

我会用...

"a".charCodeAt(0) & 0xFF
Run Code Online (Sandbox Code Playgroud)

这样就产生97了“ a”的ASCII码,这是正确的,因为它被设置了所有位的字节掩盖了。

请记住,因为在其他语言中效果很好,所以JavaScript并非总是如此。我们谈论的是在很短的时间内构思和实现的语言。