让我说我这样做:
re = /cat/;
re = /cat/;
从阅读Zakas关于Javascript的书中,似乎在执行第二行时,在内存中没有创建新的RegExp
对象。相反,re
指向同一个。这是如何工作的“引擎盖下”? Javascript是否以某种方式检查re
中已存储的内容?如果我写了怎么办?
re = /cat/;
re = /cats/;
当然,第二行会创建一个新的RegExp
对象吗? Javascript如何明确决定编写新对象或保留现有对象?
让我得出结论的书的部分说:
在ECMAScript 3中,正则表达式文字总是共享相同的 RegExp实例,始终通过构造函数创建新的RegExp 导致一个新的实例。请考虑以下事项:
var re = null, i; for (i=0; i < 10; i++){ re = /cat/g; re.test(“catastrophe”); }
在第一个循环中,只创建了一个RegExp实例 / cat /,即使它是在循环体中指定的。例 属性(在下一节中提到)不会重置,所以调用 test()每隔一次都会在循环中失败。这是因为 在第一次调用test()时找到“cat”,但是第二次调用 从索引3(最后一场比赛结束)开始搜索,但不能 找到它。由于找到了字符串的结尾,后续调用 test()从头开始。
通过“第一循环”,他指的是我发布的那个。
答案 0 :(得分:3)
作者是错误的,或者Javascript自编写以来发生了重大变化,因为现在不是这样。有关此问题的详细解答,请参阅How often does JavaScript recompile regex literals in functions?。
我怀疑作者可能将regexp 编译与RegExp
对象混淆了。当编译器看到正则表达式文字时,它可以编译一次。然后它生成每次循环运行的代码,以创建一个使用该已编译的正则表达式执行匹配的新对象。但是每个RegExp
对象都有自己的状态。
请注意,他说他正在描述EcmaScript 3.这是EcmaScript的一个非常旧版本,最初发布于1999年.EcmaScript 5是从2009年开始的(ES4在开发过程中被放弃了),这就是大多数浏览器已经实施了几年,在过去的几年中,ES6的采用正在逐步实施。也许ES3表现得像他描述的那样,但最近的版本没有。
答案 1 :(得分:1)
我不熟悉这本书,但据我所知,这就是它的工作原理。
var语句创建没有类型的新变量,并将它们附加到本地范围。
var re;
var i;
或
var re,i
null语句生成一个独立存在的null类型对象。
null
在var语句中分配变量只是将其指向该对象,但它不会成为该对象;它们是分享关系的独立事物。
var re=null,i;
使用正则表达式语句创建一个新的正则表达式对象,我们可能会或可能不会将其分配给变量。
/cat/g
或
re=/cat/g
当我重现你的例子时,它只在firefox52中返回true一次,它永远不会返回false,但如果我将测试的返回值分配给另一个变量,并记录它,我会得到十次真实。
var re=null,i;
for (i=0;i<10;i++){
re=/cat/g;
var x=re.test('catastrophe');
console.log(x)}
//returns true ten times
我认为Zacas正在解释由于他们实现了javascript而在某些浏览器中发现的怪癖。使用正则表达式或任何语句应该每次创建一个新对象,但有很多东西叫做javascript,其中很多都会尽可能频繁地重用对象,偶尔会导致最终修复的奇怪行为。
我希望有帮助