看起来像JS在两件事之间看到+
时吓坏了。不知道类型,所以它必须找到类型。我遇到了this guy (video with time stamp)的例子:
x = x | 0;
y = y | 0;
告诉JS我们正在使用数字。我需要bit
解释它是如何运作的,或者至少是外行人的术语。
如果这是告诉JS x
和y
是数字的方法,我们如何告诉JS变量是strings
,bools
等...使用这个按位运算符。另外,为什么在日常应用中不经常使用它?
答案 0 :(得分:1)
您发布的代码段位于名为“asm.js”的幻灯片上,是更大范例的一部分:
function Module() {
"use asm";
function add(x, y) {
x = x | 0;
y = y | 0;
return x + y;
}
return {add: add};
}
注意"use asm"
注释 - 它是Mozilla引入的一种方式,让JS引擎知道这段代码是为了符合asm.js specification,它定义了一个受限制的JavaScript子集,可以使用“提前”编译器编译成高效的机器代码。
除此之外:自2013年asm.js推出以来,浏览器供应商一致同意WebAssembly,这是一种新标准,可以在不使用奇怪的JavaScript语法的情况下解决同样的问题。
常规JavaScript有dynamic typing,这意味着您可以编写function add(x, y) { return x + y; }
,然后将其与不同类型的参数一起使用,例如:
add(1,2) /* =3 */
add("Hello ", "world") /* ="Hello world" */
// or even
add("1+1=",2) /* ="1+1=2" */
因此,JS引擎无法“提前”生成函数的高效代码 - 在它看到它的使用方式之前:它需要考虑传递给它的任何可能类型的参数。
带有此问题的add(int, int)
100000次然后调用add(string, string)
,优化的代码必须有防范这一点 - 然后再回到如果发生这种情况,速度较慢的模式。这是一种相当智能的技术,它通常适用于手写JavaScript,但它显然比编译静态类型代码(如C编译器那样)有更多的开销。如果您有一个C(++)代码库(通过使用EmScripten将其编译为JavaScript,则在浏览器中运行) - 例如,Unreal Engine,chess engine,{{3}等等 - 你可以比这更好。
这就是Mozilla提出asm.js的原因:C-to-JS编译器可以在生成的JS中嵌入类型注释,并允许JS引擎从一开始就有效地编译它。
a = a | 0
语法背后的想法是他们不想发明新语法,因为这会阻止使用新语法的代码在不支持它的浏览器中运行。所以他们使用这个构造,它已经将任何输入值强制转换为遵循规范的任何JS引擎中的整数,以使支持asm.js的引擎知道变量的类型。
如果这是告诉JS x和y是数字的方法,我们如何告诉JS变量是字符串,bool等...使用这个按位运算符
asm.js DOS emulator,因为C中的字符串只是指向保存字符串各个字节的内存块的指针(即整数索引)。 EmScripten编译的代码不使用JavaScript String
s。
答案 1 :(得分:0)
我认为如果你在这个网站上搜索,你会发现很多关于投射数字和javascript的特殊输入。
就个人而言,我不喜欢按位or
的配方。有几个原因,但主要是因为它似乎是一个容易找到难以检测的错误的地方。鉴于发布的视频中的功能,请考虑:
function add(x, y) {
x = x | 0
y = y | 0
return x + y
}
console.log( add(1, Infinity) )
// 1? Shouldn't that be inifinity?
console.log( add(Infinity, Infinity) )
// 0? Shouldn't that be inifinity?
console.log( add(1, {n: 4}) )
// 1? NaN seems more reasonable
console.log( add(1, undefined) )
// 1? NaN seems more reasonable

现代JS还有其他方法可以用更合理的行为来强制数字,例如Number()
:
function add(x, y) {
x = Number(x)
y = Number(y)
return x + y
}
console.log( add(2, Infinity) )
// Infinity
console.log( add(1, {m: 2}) )
// NaN
console.log( add(1, "2") )
// 3 - still casts strings as expected
console.log( add(1, [2]) )
// 3 - and single element array

有关Number()
vs parseInt()
的一件事值得一提:
console.log(parseInt("24px", 10))
// 24 - handy for browser work
console.log(Number("24px"))
// Nan - stricter

其他类型(String(23)
,Boolean(1)
等也有类似的功能。)