【问题标题】:difference between 'var a = 2' and 'this.a = 2''var a = 2' 和 'this.a = 2' 之间的区别
【发布时间】:2010-11-17 13:08:47
【问题描述】:

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

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

真正奇怪的是,在闭包内调用regexp.test(str) 会在同一输入上在truefalse 之间交替。我查看了RegExp.test 的源代码,没有发现任何可疑之处,但发生了一些事情,因为相同的字符串如何通过相同的正则表达式而失败。在看了更多RegExp.test 之后,我基本上得出结论,在RegExp.test 中声明的变量在调用之间继续存在,并且会扰乱后续调用。那么问题来了:

this.a = 2;

var a = 2;

当上述语句出现在一个被调用的方法中时,该方法在一个闭包内的一个对象上调用,该闭包包含对该对象的引用?我问是因为当我将regexp.test 移到闭包之外时,该错误消失了。当regexp.test 在闭包外被调用时,它不会在每次调用时在truefalse 之间翻转。我不知道为什么会这样。

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

【问题讨论】:

    标签: javascript closures


    【解决方案1】:

    由于您没有显示您的 RegExp,但我只是回答了类似的问题,我想您在 RegExp 中使用了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
    

    因此,要解决此问题,您需要从 RegExp 中删除 global 选项。

    免责声明,这是我之前回答的副本:
    Unusual javascript Regex result, explanation please!

    【讨论】:

    • 这个答案有什么意义?这和varthis 有什么关系?
    • 他的问题中没有varthis,他在推测RegExp.test 的内部结构,我确信其中没有this.a,因为它是本机C 代码。跨度>
    • 天哪,我怎么会错过这个。你是对的。这正是正在发生的事情。问题不是因为关闭,而是因为全局选项。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      看看this page 了解this 在JS 中的神奇之处。 this 的含义变化很大,具体取决于您使用函数的方式。

      【讨论】:

      • 啊,但是当函数作为方法调用时应该一点都不难。当作为regexp.test(str) 中的方法调用时,this 应该没有歧义,因为它指的是regexp
      • 我猜你的函数 do_something() 和你的闭包都归窗口所有。您可能会包含一些类似于 console.debug(this) 或 console.debug(this.getAttribute('id')) 的愚蠢调试代码。就您的 js 执行而言,它至少可以提供关于这是什么的线索。
      猜你喜欢
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 2017-06-14
      • 1970-01-01
      • 2019-03-20
      • 1970-01-01
      • 1970-01-01
      • 2020-12-28
      相关资源
      最近更新 更多