【问题标题】:javascript new keyword - Returning new object created inside inner anonymous functionjavascript new 关键字 - 返回在内部匿名函数中创建的新对象
【发布时间】:2012-10-12 03:22:22
【问题描述】:

我正在浏览一本关于 DOM 脚本的书,当他们谈论 Ajax 时,书中出现了以下函数。

function getHTTPObject() {

    if(typeof XMLHTTPRequest == "undefined")
        XMLHTTPRequest = function() {
           try { return new ActiveXObject("Msxml2.XMLHTTP.6.0");}
           catch(e) {}

           //several more fall through try/catch blocks attempting 
           //to create different XMLHTTP objects. 
           //If none succeed...

           return false;
        }

     return new XMLHTTPRequest();
}

如果尝试在分配给 XMLHTTPRequest 的内部匿名函数中创建 ActiveXObject 时在 try/catch 块中使用 new 关键字,为什么在 getHTTPObject 结束时返回 XMLHTTPRequest 的结果时再次使用 new 关键字()?

似乎它正在返回一个新的新对象。

编辑

我大致了解代码的用途,检查 XMLHTTPRequest 构造函数是否存在,如果不存在,则定义一个尝试生成 XMLHTTP ActiveXObjects 的构造函数。到目前为止,我和你在一起。

假设 XMLHTTPRequest 未定义。

XMLHTTPRequest 被分配了内部函数构造函数。

然后在getHTTPRequest的底部调用XMLHTTPRequest。

在 XMLHTTPRequest 中,创建一个新的 ActiveXObject 并将其返回给调用者,在本例中为 getHTTPObject。现在 getHTTPObject 又将这个对象返回给它的调用者。但同样,为什么行:

return new XMLHTTPRequest() 

如果新的(即对象实例化)已经出现在 XMLHTTPRequest() 的定义/范围内的 try 块的代码中,是否需要新的?为什么不简单:

return XMLHTTPRequest()

感谢大家的回答。很有可能,甚至可能是我对 JS 构造函数语法的掌握不够强,这就是让我在这里绊倒的原因。

【问题讨论】:

    标签: javascript


    【解决方案1】:

    立即返回并退出代码块。这些回报中只有一个会受到打击。

    【讨论】:

    • 在下面查看我对 RobG 的评论。很确定这是不正确的。内部匿名函数的返回不是从getHTTPObject返回,而是从XMLHTTPRequest返回。因此,在最后一行代码中,getHTTPObject 本身调用了 XMLHTTPRequest,其中的返回将您弹回 getHTTPObject 的范围,然后最后一行的返回将您弹回之前的调用函数。
    【解决方案2】:

    你误解了代码。

    > function getHTTPObject() {
    > 
    >     if(typeof XMLHTTPRequest == "undefined")
    >         XMLHTTPRequest = function() {
    

    如果标识符XMLHTTPRequest未定义,则分配以下函数。

    >            try { return new ActiveXObject("Msxml2.XMLHTTP.6.0");}
    >            catch(e) {}
    > 
    >            //several more fall through try/catch blocks attempting 
    >            //to create different XMLHTTP objects. 
    >            //If none succeed...
    > 
    >            return false;
    >         }
    

    现在调用 XMLHttpRequest,它将是主机提供的函数或上面分配的函数。

    >      return new XMLHTTPRequest(); }
    

    以上假设如果标识符 XMLHttpRequest 解析为 undefined 以外的其他内容,则它是可调用的并返回一个 XMLHttpRequest 实例。

    【讨论】:

      【解决方案3】:

      你提到的try块只有在if条件下才会执行

      if(typeof XMLHTTPRequest == "undefined")
      

      保持良好。如果没有,则直接到达getHTTPObject()方法末尾的return语句,然后返回新的XMLHTTPRequest对象。

      因此,要么返回新的ActiveXObject,要么返回新的XMLHTTPRequest

      【讨论】:

      • 不,if 决定是否将函数对象分配给 XMLHTTPRequest。如果它未定义,它会通过将内部函数分配给它来定义它。不管 if 是真还是假,XMLHTTPRequest 都会在 getHTTPObject 的最后一行被调​​用,这只是你是调用浏览器已经存在的这个函数的定义还是调用那个内部函数提供的.
      • @MTLPhil:我认为这个答案是正确的。关键是如果XMLHTTPRequest 定义的,那么在另一个函数中的new 将永远不会被调用,所以你仍然需要在本机XMLHTTPRequest 函数上调用new。如果条件确实通过,那么是的,有两个new 调用,但这没关系。从分配的函数创建的对象将被 ActiveXObject 覆盖
      • 所以在没有定义 XMLHTTPRequest 并且使用了我们自己的滚动定义的情况下,getHTTPObjects 返回语句中的外部“新”关键字是完全多余的吗?但是在实际定义 XMLHTTPRequest 的情况下,它必须存在才能正确构造对象?
      【解决方案4】:

      内部构造函数不会在外部构造函数之前调用。 相反,如果 XMLHTTPRequest 函数不存在,则首先定义它,然后 then 作为构造函数调用。

      它首先检查 XMLHTTPRequest 是否存在(无论是原生的,还是来自先前调用的。如果存在,则将其作为构造函数调用。如果不存在,则首先创建它。

      这里的一个技巧是,如果构造函数返回一个对象,new 对象不是被分配的对象,而是被返回的对象。通常,这会导致立即进行垃圾收集。一个聪明的解释器可能会意识到它根本不需要分配。这就是新创建的构造函数所做的——返回一个不同的对象。 (见http://www.gibdon.com/2008/08/javascript-constructor-return-value.html

      创建的 XMLHTTPRequest 替换了浏览器的。浏览器自带的 XMLHTTPRequest 构造函数不能作为函数调用,需要作为构造函数调用,所以新创建的对象也必须作为构造函数调用。


      请注意,这通常是库或工具包(例如 jQuery)的工作,以选择正确的 AJAX 对象。

      【讨论】:

        【解决方案5】:

        JavaScript 允许从其构造函数返回另一个对象;构造函数在这里定义:

        XMLHTTPRequest = function() {
               try { return new ActiveXObject("Msxml2.XMLHTTP.6.0");}
        

        如果new ActiveXObject("Msxml2.XMLHTTP.6.0") 成功,则生成的对象将返回给任何调用XMLHTTPRequest 作为构造函数的调用者。

            return false;
        

        这个语句只会返回一个XMLHTTPRequest 类型的空对象,因为false 本身不是一个对象。

        最后getHTTPObject() 需要返回一个对象,而不仅仅是构造函数,这就是为什么你会在最后看到return new XMLHTTPRequest();

        另请参阅ECMAScript Language Specification 中此行为的干版。

        【讨论】:

        • 仅当函数被调用(作为构造函数)时。诀窍是它很可能不会。
        猜你喜欢
        • 2012-07-30
        • 1970-01-01
        • 1970-01-01
        • 2022-11-10
        • 2014-02-20
        • 1970-01-01
        • 1970-01-01
        • 2013-05-13
        • 2011-11-05
        相关资源
        最近更新 更多