【问题标题】:`this` object in require().function()require().function() 中的 `this` 对象
【发布时间】:2015-05-14 15:32:44
【问题描述】:

在处理robots 节点库时,我注意到了

var robots = new require('robots').RobotsParser();

不同于

var robots = new (require('robots')).RobotsParser();

第一个 require 失败,感叹 this.someFunction() 不存在,而第二个成功。 出于某种原因,上面第一行中的this 对象显然是指全局对象,而在第二行中它绑定到robots 模块。为什么?

我收到的错误是:

/home/user/crawler/lib/robots/lib/parser.js:44
    this.setUrl(url, after_parse);
         ^
TypeError: Object #<Object> has no method 'setUrl'

setUrl 是示例中提到的实际someFunction

【问题讨论】:

  • 我投票决定将此问题作为离题结束,因为 OP 没有遵循 usage instructions 的回购协议,然后对它不起作用感到惊讶。
  • @Mathletics 有一个错误的用法,但它仍然展示了一个可以回答的意外行为的特殊情况。 IMO 称其为题外话是矫枉过正。
  • @E_net4 这就是投票系统的美妙之处:我只有一票。无论如何,发现了一个真正的骗子。
  • @davide requirethis 之间没有关系; require 只是一个函数,就像 JS 中的任何其他函数一样。

标签: javascript node.js this require


【解决方案1】:
var robots = new require('robots').RobotsParser();

被解析为

var robots = (new require('robots')).RobotsParser();

即它尝试调用require() 实例的RobotsParser 方法。 不是你想要的!

【讨论】:

    【解决方案2】:

    第一行调用require 的构造函数,这有效地修改了库范围内的this 引用以指向一个新的、假定的require 实例。这是不正确的,require 应始终作为常规函数调用。添加括号(如第二行)可以解决问题,因为它会创建一个新的 RobotsParser 实例。

    【讨论】:

    • 谢谢@E_net4。我很困惑,因为成员访问运算符(.)的优先级高于new,但这似乎不是运算符优先级的问题。你能指点我一些对此有阴影的文档吗?
    • 您的问题似乎与操作员优先级有关。编写new foo().a() 将调用foo 的新实例的成员函数a。如果您想知道this 是如何工作的,只需进行一次小搜索即可找到一些好的资源。看看this one
    • 谢谢,我已经阅读了关于“JS 很性感”的链接文章。不过,我不明白为什么在new foo().a() 中,函数a 是在foo 的新实例上调用而不是旧实例。如果new的优先级低于.,为什么成员函数anew之后执行? MDN 文档在这个具体细节上似乎很肤浅。
    • 它确实具有较低的优先级。行为定义明确,与您的想法相反。此外,也没有旧实例,只是无意中创建了一个新实例。
    猜你喜欢
    • 2015-01-22
    • 2011-12-02
    • 2014-12-01
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多