2013-07-04 196 views
1

我在写Javascript对象构造函数时遇到了麻烦。当我在其中一个实例化对象上调用函数时,它总是返回实例化对象的值。流程是这样的:Javascript对象返回原型

blue = tool('blue'); 
blue.jDom();  // returns '[<div id="blue" class="tool">...</div>]' 
red = tool('red'); 
red.jDom();  // returns '[<div id="red" class="tool">...</div>]' 
blue.jDom();  // returns '[<div id="red" class="tool">...</div>]' 

我相信这是由于我包含在原型声明中的私有变量。如果我将原型声明移动到构造函数中,一切正常,但这只是掩盖了这样一个事实,即通过为每个对象创建一个新的原型,似乎我的对象正在影响原型的属性,而不是它们本身。这里是我的相关代码:

function beget(oPrototype) { 
    function oFunc() {}; 
    oFunc.prototype = oPrototype; 
    return new oFunc() 
};  

var tool = (function(){ 
     var protoTool = function(){ 

      var oTool = {}, 
       that = this, 
       _bVisible = true, 
       _oParentPane = 'body', 
       _aoComponents, 
       _sName = 'tool', 
       _sSelector = '#' + _sName, 
       _jDomElement; 



      // this is the private tab object, needs to be refactored 
          // descend from a single prototype 
      function _tab() { 

       var oTab = {}, 
        _sHtml = '<li><a href="' + _sSelector + '">' + _sName + '</a></li>', 
        _jDomElement = $(_sHtml); 

       function jDom() { 
        return _jDomElement; 
       } 

       oTab.jDom = jDom; 

       return beget(oTab); 
      }; 

      // this builds the jDom element 
      function _jBuild() { 
       var sHtml = '<div id="' + _sName + '" class="tool"></div>'; 
       _jDomElement = $(sHtml) 
       return _jDomElement; 
      }; 

      // this returns the jQuery dom object 
      function jDom() { 
       if (typeof _jDomElement === 'undefined') { 
        _jBuild(); 
       } 
       return _jDomElement; 
      }; 

      function configure (oO){ 
       if (typeof oO !== 'undefined') { 
        if (typeof oO === 'string') { 
         var name = oO; 
         oO = Object(); 
         oO.sName = name; 
        } 


        _bVisible = oO.bVisible || _bVisible, 
        _oParentPane = oO.oParentPane || _oParentPane, 
        _aoComponents = oO.aoComponents || _aoComponents, 
        _sName = oO.sName || _sName, 
        _sSelector = '#' + _sName, 
        _jDomElement = undefined; 
        _oTab = _tab(); 

        _oTab.jDom() 
         .appendTo(jDom()) 
         .draggable({ 
         revert: 'invalid', 
         containment: '#main', 
         distance: 10, 
        }); 
       } 

      }; 

      oTool.tMove = tMove; 
      oTool.bVisible = bVisible; 
      oTool.uOption = uOption; 
      oTool.jDom = jDom; 
      oTool.configure = configure;  

      return oTool; 
     }(); 

     var tool = function (oO) { 
      that = beget(protoTool); 
      that.configure(oO); 
      that.configure = undefined; 
      return that; 
     }; 

     return tool; 
    })(); 
+0

你为什么写这个复杂的代码?什么是如此艰难的构造函数分配字段,然后将外部方法分配给原型。它将*只是工作*。 – Esailija

回答

0

第一:在内部工具var定义中,由'that = beget(protoTool);'你必须表示'var that = beget(protoTool);'

代码中发生了什么? :
对工具定义进行评估以赋予工具一个值。在评估过程中,围绕protool进行封闭。
但是在这个评估过程中,这个闭包只做了一次:所有后来对protool的调用(通过调用'that'作为protools的原型)将改变这个第一个和唯一的闭包的值。
这就是为什么你会看到这种行为:最新看到的对象将更新闭包值,因此会引起所有关注。
解决方案是在'工具'内部的var函数定义中创建正确的闭包。

但是,如果我可以,我会建议完全去一个经典的JavaScript类定义,使用后面的新运营商,这是,我相信,更容易编码/理解/调试。

另一个rq:beget === Object.create中最新的javascript规范(1.8.6)