2014-10-01 73 views
1

好的,我怀疑这是一种独特的情况,所以无论是有人已经这样做了,或者有人认为这是不可能的,至少在我问的方式。Javascript原型 - 需要帮助添加帮助器原型

我有2个原型变量(功能),一个是父母,另一个是帮手。我想要做的是从助手内引用父对象,以便每个父对象的每个实例都可以使用助手,同时允许助手实质上扩展父对象。我使用jQuery和JavaScript。

这里有一个简单的例子:

var Parent = function(identity) { 
    this.identity = identity; 
    this.group = $(this.identity); 
    this.helper = new Helper(this); 
    return this; 
}; 
Parent.prototype = { 
    _setup : function(dolisten) { 
     dolisten = dolisten || false; 
     var that = this; 
     that.group.each(function(i) { 
      if ($(this).data('key') !== 'undefined') { 
       that.elems[i] = new Object(); 
       that.elems[i].key = parseInt($(this).data('key')); 
       // build out rest of elems object 
      } 
     }); 
     if (dolisten) { 
      this._listen(); 
     } 
    }, 
    _listen : function() { 
     var that = this 
     $('body').on('click tap', that.identity, function() { 
      that.helper._showbusy(this, true); 
      // do some other stuff 
     } 
    } 
}; 
var Helper = function(reference) { 
    this.reference = reference; 
}; 
Helper.prototype = { 
    _showbusy : function(elem, isbusy) { 
     console.log(this.reference); 
     // do some stuff to elem 
    }, 
}; 

这工作,但来自其自身.helper节点内产生实质上无限引用父。所以,如果没有每次都实际传递父对象(希望只创建一个引用点,上面的代码似乎会导致引用“循环”?),这可以优雅地完成吗?

最后,我想是一个简单的:

var obj = new Parent('.myClass'); 
console.log(obj); 
// result : Parent { identity:'.myClass', group: [Object object], helper: {reference : *Parent without helper key included, which is where the looping seems to occur}, etc... 

编辑:暂时,我诉诸传递由助手需要父母的特定按键。这可以防止助手无限级联到父级副本和自身,但是更优雅的解决方案,其中帮助者可以访问整个父级,而不是只传递特定的键,而不需要级联助手引用父级成为父级 - >助手 - > parent - > helper - > parent - > etc ...

+0

http://javascript.crockford.com/private。html有一个阅读。为你的“助手”使用“特权”对象 – Mike 2014-10-01 17:29:15

+0

你想要什么? '家长'赠送'助手',反之亦然? – 2014-10-01 17:45:41

+0

我希望帮助器的每个实例都可以使用帮助器的功能 - 所以我希望帮助器可以扩展父代,但可能有一个实例,我说,兄弟姐妹是父代的兄弟,在辅助器中也需要一些功能,其中helper使用任何函数调用它的私有变量(在父节点中的'this'!'this'在兄弟节点中,但'父'或兄弟节点中的'this'可由助手访问)。 – Lazerblade 2014-10-01 18:13:03

回答

1

你所说的是称为循环引用,它被定义为两个互相引用的数据结构。

var a = {value: 'A'}; 
var b = {value: 'B'}; 
a.b = b; 
b.a = a; 

console.log(a.b.a.b.a.b.a.b.a.b.a.b.value); // 'B' 

并且在大多数情况下,这实际上是可以的。现代垃圾收集器足够聪明,可以在对象过期时清理它,所以内存应该处理得很好。大量的JS代码存在循环引用的对象。

你会遇到的最大问题是如果你想将对象编码为JSON,或者对对象进行任何递归操作。

// continued code form above 
JSON.stringify(a); 
// TypeError: Converting circular structure to JSON 

由于JSON生成是一个递归的过程,它的钻进每这将被锁定在循环引用,并产生JSON无限量属性。

There are some ways handle that though

+0

我最担心的是,尽管大多数浏览器中的现代垃圾收集器都可以处理这些问题,但这会导致内存泄漏或内存使用过多,更重要的是,它会影响内存有限的设备(移动设备,平板电脑,较旧的设备台式机/笔记本电脑)? – Lazerblade 2014-10-01 18:22:44

+0

过去5年中制造的大多数手机/平板电脑都会在浏览器中运行更现代化的JS引擎,而IE 6,7,8的老式桌面版本则会发生严重泄漏。 [更多信息](http://stackoverflow.com/questions/1999840/javascript-circular-references-and-memory-leaks)。老实说,我不会为此担心。如果你的代码有内存问题,它不会是因为循环引用。 – 2014-10-01 18:27:49

+0

恩,谢谢你的回答。我希望能有另一种方式来做到这一点,但如果按照我所做的方式做到这一点很好,那么我想我不应该关心“级联”或循环引用。在给出答案之前,我会给别人一个提供替代方案的机会,但如果没有其他人能提供更好的解决方案,那么您就赢了。 ;) – Lazerblade 2014-10-01 18:32:11

0

我做了一些调整,我的代码和console.logging后的结果,这似乎是干净多了。我将此作为潜在答案发布,因为我可以编辑我的问题,但我希望在问题和答案之间将反馈分开,并查看是否有任何人有任何可能的更改或替代方案,这可能会提供更好的解决方案。

现在,我要去这一点:

var Parent = function(identity) { 
    if (identity) { 
     this.identity = identity; 
     this.group = $(this.identity); 
     if (this.group.length > 0) { 
      this.elems = new Array(); 
      this.helper = new Helper(this); 
      this._setup(true); 
     } 
    } 
    return this; 
}; 

var Helper = function(reference) { 
    for (var key in reference) { 
     if (!this[key]) { 
      this[key] = reference[key]; 
     } 
    } 
}; 

,并从那里酌情延长。

+0

你只需将所有属性复制到帮助器中?这避免了循环引用,但是如果在初始化之后'parent'的任何属性都改变了,'helper'就不知道了。如果你打算去那条路线,直接将辅助方法直接放在'Parent'上会更清洁。 – 2014-10-01 22:32:12

+0

问题是,我没有从helper中调用任何helper函数,我从父类调用它们。例如,我有一个帮助函数,一旦按下按钮就会改变按钮的状态,以向用户显示该按钮已被按下,并且它正在等待响应(发出ajax调用)。助手是勺子喂养它需要改变按钮状态的对象。我也将使用相同的方法从父级的同级调用按钮功能。帮手的目的是减少重复编码,而不是交叉共享变量本身。喂入,得到回报。 – Lazerblade 2014-10-02 11:49:07

+0

此外,我正在处理的网站必须与IE8兼容(不幸),并且占用的空间尽可能小。尽管上面提到的内存泄漏问题的链接并不直接与我正在做的事情相关,但可能会产生影响,所以我希望通过保持简单性来避免此问题。 – Lazerblade 2014-10-02 11:56:47