'var a = 2' 之间的区别和“this.a = 2”

发布于 2024-10-02 13:15:35 字数 1084 浏览 1 评论 0原文

我刚刚在一些处理 RegExp.test 的 javascript 代码中发现了最奇怪的错误。我在函数内声明了一个正则表达式 regexp ,并且有一个引用 regexp 的闭包,并且我使用该闭包迭代要测试的字符串数组借助来自prototype.js的collect,即

function some_func() {
  var regexp = /regular_expression/;
  an_array_of_strings.collect(
     function(str) {
       if (regexp.test(str)) {
         do_something();
       }
     }
  );
}

真正奇怪的是,在闭包内调用regexp.test(str)会在true<之间交替/code> 和 false 在同一输入上。我查看了 RegExp.test 的源代码,没有发现任何可疑之处,但确实发生了一些事情,因为同一个字符串如何能够通过和失败相同的正则表达式。在仔细研究了 RegExp.test 后,我基本上得出结论,在 RegExp.test 中声明的变量在调用之间继续存在,并且扰乱了后续调用。 什么区别

this.a = 2;

var a = 2;

所以问题是:上述语句出现在对持有该对象引用的闭包内的对象调用的方法中, ?我这么问是因为当我将 regexp.test 移到闭包之外时,错误就会消失。当在闭包外部调用 regexp.test 时,它不会在每次调用时在 true 和 false 之间翻转。我不知道为什么会发生这种情况。

编辑:当我将regexp移到闭包之外时,我忘记添加全局选项,这就是错误消失的原因。谢谢伊沃

I just discovered the weirdest bug in some javascript code dealing with RegExp.test. I had a regular expression regexp declared inside a function and I had a closure that had a reference to regexp and I was using the closure to iterate over an array of strings to test them with the help of collect from prototype.js, i.e.

function some_func() {
  var regexp = /regular_expression/;
  an_array_of_strings.collect(
     function(str) {
       if (regexp.test(str)) {
         do_something();
       }
     }
  );
}

The really weird thing was that calling regexp.test(str) inside the closure would alternate between true and false on the same input. I looked at the source for RegExp.test and I didn't see anything fishy but there was something going on because how can the same string pass and fail the same regular expression. After staring some more at RegExp.test I basically concluded that variables declared in RegExp.test were continuing to exist between invocations and were messing up subsequent invocations. So here's the question: What is the difference between

this.a = 2;

and

var a = 2;

when the above statements appear inside a method being called on an object inside a closure that holds a reference to that object? I'm asking because the bug disappears when I move regexp.test outside the closure. When regexp.test is called outside the closure then it doesn't flip-flop between true and false on each call. I have no idea why this is happening.

Edit: When I was moving the regexp outside the closure I was forgetting to add the global option so that's why the bug was disappearing. Thanks Ivo.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

乄_柒ぐ汐 2024-10-09 13:15:35

由于您没有显示您的正则表达式,但我只是回答了与此类似的问题,我想您在正则表达式中使用了 global 选项,这有一些有趣的副作用。

与 exec 一样(或与
它),测试多次调用
相同的全局正则表达式
实例将前进超过
上一场比赛。

来源:https://developer.mozilla.org/en/JavaScript/ Reference/Global_Objects/RegExp/test

所以这里到底发生的是,由于您使用正则表达式的全局选项,它将在找到匹配项后继续搜索字符串。

regexp.test("d")

这将在位置 0 找到 d。

regexp.test("d")

现在将从位置 1 开始搜索 d,但由于这是字符串的末尾,因此它将找不到任何内容,因此返回false

我们可以使用正则表达式的 lastIndex 属性来证明:

regexp.lastIndex
>> 0
regexp.test("d")
>> true
regexp.lastIndex
>> 1
regexp.test("d")
>> false

因此,要解决该问题,您需要从正则表达式中删除 global 选项。

免责声明,这是我之前答案的副本:
异常的 javascript 正则表达式结果,请解释!

Since you didn't show your RegExp but I just answered something similar to this, I suppose that you're using the global option in your RegExp, which has some interesting side effects.

As with exec (or in combination with
it), test called multiple times on the
same global regular expression
instance will advance past the
previous match.

Source: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/test

So what exactly happens here is that since you're using the global option for the regex, it will continue to search the string after it found an match.

regexp.test("d")

This will find d at position 0.

regexp.test("d")

This will now search for d starting at position 1, but since that's the end of the string it will not find anything therefore returning false.

We can use the lastIndex property of the regex to proof that:

regexp.lastIndex
>> 0
regexp.test("d")
>> true
regexp.lastIndex
>> 1
regexp.test("d")
>> false

So to solve the issue you need to remove the global option from your RegExp.

Disclaimer, this is a copy of my previous answer:
Unusual javascript Regex result, explanation please!

纸短情长 2024-10-09 13:15:35

这是一个棘手的问题,因为乍一看它们似乎是相同的。

我猜测 this.a 属于该函数,但也可能会延长该函数的生命周期,而不仅仅是函数调用本身;而var a会在每次执行函数时被创建和销毁。

This is a tricky question, as at first glance they appear to be identical.

I would surmise that this.a is owned by the function, but may also extend for the life of that function, not just the function call itself; whereas var a would be created and destroyed each time the function is executed.

神魇的王 2024-10-09 13:15:35

看看此页面了解this的奇妙之处JS。 this 的含义会发生很大的变化,具体取决于您如何使用函数。

Have a look at this page about the wonders of this in JS. The meaning of this changes quite dramatically, depending on how you use your functions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文