Javascript 告诉JS我在使用数字的方法(优化)

Javascript 告诉JS我在使用数字的方法(优化),javascript,optimization,bitwise-operators,Javascript,Optimization,Bitwise Operators,当看到+介于两件事之间时,JS似乎会抓狂。不知道类型,因此必须找到类型。我遇到了世卫组织的例子: x = x | 0; y = y | 0; 告诉JS我们正在使用数字。我需要bit解释它在引擎盖下是如何工作的,或者至少用外行的话说 如果这是告诉JSx和y是数字的方法,那么我们如何告诉JS变量是字符串,布尔值等等。。。使用此按位运算符。还有,为什么在日常应用程序中不经常使用它呢?我想如果你在这个网站上搜索,你会发现很多关于铸造数字和特殊类型的javascript的信息 就个人而言,我不喜欢按位或

当看到
+
介于两件事之间时,JS似乎会抓狂。不知道类型,因此必须找到类型。我遇到了世卫组织的例子:

x = x | 0;
y = y | 0;
告诉JS我们正在使用数字。我需要
bit
解释它在引擎盖下是如何工作的,或者至少用外行的话说


如果这是告诉JS
x
y
是数字的方法,那么我们如何告诉JS变量是
字符串
布尔值
等等。。。使用此按位运算符。还有,为什么在日常应用程序中不经常使用它呢?

我想如果你在这个网站上搜索,你会发现很多关于铸造数字和特殊类型的javascript的信息

就个人而言,我不喜欢按位
的公式。有几个原因,但主要是因为它似乎是一个容易发现难以检测的bug的地方。考虑到发布的视频中的功能,请考虑:

函数添加(x,y){
x=x | 0
y=y | 0
返回x+y
}
console.log(添加(1,无穷大))
// 1? 这不应该是不有限的吗?
console.log(添加(无限,无限))
// 0? 这不应该是不有限的吗?
log(添加(1,{n:4}))
// 1? 南似乎更合理
console.log(添加(1,未定义))

// 1? NaN似乎更合理
您发布的代码片段位于一张名为“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引擎知道此代码旨在符合,它定义了JavaScript的受限子集,可以使用“提前”编译器将其编译成高效的机器代码

旁白:自2013年引入asm.js以来,浏览器供应商已经达成一致,这是一个新标准,它在不使用奇怪的JavaScript语法的情况下解决了同样的问题。

常规JavaScript具有,这意味着您可以编写
函数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引擎无法“提前”为函数生成有效的代码——在它看到如何使用它之前:它需要考虑传递给它的任何可能类型的参数

出现此问题的JS引擎是:

  • 缓慢启动-通过生成字节码并通过解释器运行它,同时观察变量的实际类型
  • 当代码的某些部分变得“更热”(即重复运行)时,它们会更积极地使用在步骤1推断的类型重新编译(“及时”)
  • 由于推断的类型不能保证保持不变(例如,您可以调用
    add(int,int)
    100000次,然后调用
    add(string,string)
    ,因此优化的代码必须对此进行防范——如果发生这种情况,则返回较慢的模式
这是一种相当聪明的技术,它通常适用于手工编写的JavaScript,但它显然比编译静态类型的代码(像C编译器一样)有更多的开销。如果你有一个C(++)代码库(你可以在浏览器中使用编译成JavaScript来运行),比如说,a,a等等,你可以做得更好

这就是Mozilla提出asm.js的原因:C-to-js编译器可以将类型注释嵌入到生成的js中,并允许js引擎从一开始就高效地编译它

a=a | 0
语法背后的想法是,他们不想发明一种新语法,因为这会阻止使用新语法的代码在不支持它的浏览器中运行。因此,他们使用这种结构,这种结构已经将任何JS引擎中的输入值强制为符合规范的整数,让支持ort asm.js知道变量的类型

如果这是告诉JS x和y是数字的方法,我们如何告诉JS变量是字符串、布尔等…使用这个位运算符


asm.js,因为C中的字符串只是指向存储字符串各个字节的内存块的指针(即整数索引)。EmScripten编译的代码不使用JavaScript
string
s。

生成32位整数……这可能没问题,但如果使用的数字是a,则会把事情搞砸。)非整数,或b)在32位(有符号?)整数范围之外,大约+/-20亿
警报(+“5”+“7”)
警报(“5”-“7”)
警报(“5”*1+“7”*1)以及我是否应该在每次添加两个数字时使用例如Number(x)+Number(c)?这会提高脚本的性能吗?我怀疑它会提高性能,但我从未测试过它。除非真的有必要,否则我很少看到JS代码带有显式强制。我认为大多数JS已经学会了接受弱类型并享受灵活性。那些需要强类型的函数使用Typescript。
|0
技巧的要点是指出函数需要(并且您承诺提供)一个整数,而不是JS
数字或任何其他类型。添加两个整数是一条机器指令,而添加两个JS
Number
s必须考虑更多的可能性:浮点、
无穷大、
NaN
-0
等等。@Learnonhardway:你不应该使用
Number(x)+Number(c)
,相反,确保
x
c
具有稳定的类型:例如整数。这可以让JS引擎优化函数,但与类型不一致会严重影响性能。@Nickolay我理解-我对这个问题的解释是“这是告诉JS x和y是数字的方式吗?”有时,显式转换一个数字很重要,但这不是做这件事的方法。在那里读的好文章。在我读过这篇文章之后,可能会回到这篇文章。另外,VarA=Number(3)比VarA=3好吗?如果