【问题标题】:javascript classes scope and anonymous functionsjavascript 类作用域和匿名函数
【发布时间】:2011-12-11 16:35:42
【问题描述】:

我声明了一个 javascript 类,如下所示。我的问题是匿名函数看不到该类的范围。我无法从 ajax 调用加载回调中引用 bb_obj ..

有没有办法做到这一点?

提前谢谢..

dojo.declare("sop.quote", null,
{
   bb_obj : new Object,

   stage1 : function()
   {
      dojo.xhrPost(
      {
         url      :  'go/module_service/transport.php',
         content  :  this.bb_obj,
         handleAs :  'xml',
         load     :  function(xml)
         {
            var status  = xml.getElementsByTagName("STATUS")[0].childNodes[0].nodeValue;
            var message = xml.getElementsByTagName("MESSAGE")[0].childNodes[0].nodeValue; 

            this.bb_obj.message = message;
         },
         error    : function()
         {
         }
      }
   }
}

【问题讨论】:

    标签: javascript methods dojo scope anonymous-methods


    【解决方案1】:

    XHR 回调函数中的this 指的是XHR 对象。引用bb_obj 的唯一方法是直接引用创建的对象,在与函数相同的范围内。因为对象是通过引用传递的,所以下面的代码可以按预期工作。

    注意,为避免混淆,我使用var bb_obj_obj={} 声明了该对象。 bb_obj 属性指的是bb_obj_obj

    • bb_obj_obj.message改了
    • bb_obj 指向 bb_obj_obj,因此 bb_obj.message 指的是同一个变量

    代码:

    var bb_obj_obj = {}; //new Object
    dojo.declare("sop.quote", null,
    {
       bb_obj : bb_obj_obj,
    
       stage1 : function()
       {
          dojo.xhrPost(
          {
             url      :  'go/module_service/transport.php',
             content  :  this.bb_obj,
             handleAs :  'xml',
             load     :  function(xml)
             {
                var status  = xml.getElementsByTagName("STATUS")[0].childNodes[0].nodeValue;
                var message = xml.getElementsByTagName("MESSAGE")[0].childNodes[0].nodeValue; 
    
                bb_obj_obj.message = message; //Without `this`
             },
             error    : function()
             {
             }
          }
       }
    }
    

    另一种方法是将this 保存在一个变量中,例如。 $this:

    ...
    stage1 : function()
    {
        var $this = this;
        dojo.xhrPost({
         ...
         load     :  function(xml){
            var status  = xml.getElementsByTagName("STATUS")[0].childNodes[0].nodeValue;
            var message = xml.getElementsByTagName("MESSAGE")[0].childNodes[0].nodeValue; 
    
            $this.bb_obj.message = message; //Using `$this` instead of `this`
         },
    ...
    

    【讨论】:

    • 或者先创建对this的引用:var self = this;
    • 更具体:在stage1 : function () { 中,第一行应该是var self = this;,然后你可以使用content : self.bb_obj。这比上面答案中提出的解决方案要好。
    • @gryzzly 不要使用selfself 已定义为保存当前 window 对象的值。
    • @RobW 在道场?奇怪,我认为global 应该用于存储对window 的引用。无论如何,也许使用that。我个人不喜欢$this。使用 $ 为名称添加前缀是突出显示 jQuery 对象的惯例(我也不喜欢匈牙利符号),因此可能会造成混淆。使用that 是由 Crockford 推广的,所以使用它也许是个好主意。 (我个人的偏好是self,但如果已经使用,我会使用that)。
    【解决方案2】:

    在这种情况下,典型的 Javascript 实践是将整个内容包装在一个未命名的函数中。该函数的所有局部变量都可以被其中声明的每个对象/函数访问。通过立即调用这个未命名的函数,您可以确保函数内的代码得到执行。

    (function() {
     var bb_obj = {}
    
     dojo.declare("sop.quote", null,  {
       stage1 : function()
       {
          dojo.xhrPost(
          {
             url      :  'go/module_service/transport.php',
             content  :  this.bb_obj,
             handleAs :  'xml',
             load     :  function(xml)
             {
                var status  = xml.getElementsByTagName("STATUS")[0].childNodes[0].nodeValue;
                var message = xml.getElementsByTagName("MESSAGE")[0].childNodes[0].nodeValue; 
    
                bb_obj.message = message;
             },
             error    : function()
             {
             }
          }
       }
    })() 
    

    【讨论】:

    • 语法错误:function(){}() 至少应该写成:(function(){})()。此外,闭包并不重要,因为bb_obj 没有以var 为前缀。
    猜你喜欢
    • 2011-12-15
    • 2011-03-11
    • 2011-06-22
    • 2017-08-13
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多