2013-01-18 36 views
0

我有一個基本上是原生Javascript Array的類,但是當項目被添加或刪除時它會引發事件。Javascript在IE中有StackOverflow,但不是Chrome/Firefox

hb.extend({ 
Classes: { 
    Collection: hbClass.inherit({ 
     init: function (arr) { 
      // get the functions we want to retain 
      var _on = this.on, 
       _trigger = this.trigger, 
       _push = this.push, 
       _remove = this.remove, 
       _reset = this.reset, 
       _from = this.fromArray, 
       _watch = this.watch; 

      // Set the object up as an Array 
      this.__proto__ = Array.prototype; 

      // get the Array functions we want to use 
      this.arrPush = this.push; 

      // reapply the old functions 
      this.push = _push; 
      this.remove = _remove; 
      this.reset = _reset; 
      this.fromArray = _from; 
      this.on = _on; 
      this.trigger = _trigger; 
      this.watch = _watch; 

      if (arr && (arr.length && typeof arr !== "string")) this.fromArray(arr, true); 
     }, 

     fromArray: function (arr, stopEvent) { 
      this.reset(); 
      for (var i = 0, len = arr.length; i < len; i++) { 
       this.arrPush(arr[i]); 
      } 
      if (!stopEvent) this.trigger('change', this); 
     }, 

     push: function() { 
      this.arrPush.apply(this, arguments); 
      this.trigger('add', this); 
      this.trigger('change', this); 
      return this; 
     }, 

     remove: function (from, to) { 
      var rest = this.slice((to || from) + 1 || this.length); 
      this.length = from < 0 ? this.length + from : from; 

      this.arrPush.apply(this, rest); 
      this.trigger('remove', this); 
      this.trigger('change', this); 
      return this; 
     }, 

     reset: function() { 
      this.length = 0; 
      this.trigger('change', this); 
      this.trigger('remove', this); 
     } 
    }) 
} 
}); 

可能有更好的方法來做到這一點,但它對我來說.......除了在IE瀏覽器。
push方法下的行this.arrPush.appy(this, arguments);的IE中,它遇到堆棧溢出錯誤。
具體做法是:

SCRIPT28:堆棧空間不足

但這並不發生在Firefox或Chrome。
任何人有任何建議?
編輯
觸發代碼:

this.hbClass.prototype.trigger = function(type, data, context) { 
    var listeners, handlers, i, n, handler, scope; 
    if (!(listeners = this.listeners)) { 
     return; 
    } 
    if (!(handlers = listeners[type])){ 
     return; 
    } 
    for (i = 0, n = handlers.length; i < n; i++){ 
     handler = handlers[i]; 

     if (handler.method.call(
      handler.context, this, type, data 
     )===false) { 
      return false; 
     } 
    } 
    return true; 
} 
+0

你爲什麼要指定'this.push'到'_push',然後就重新分配,早('this.push ='_push')。 – natlee75

+1

您使用哪個IE? – natlee75

+0

@ natlee75:IE 9.此外,在'init'中,'this .__ proto__ = Array.prototype;'這行基本上將'Collection'設置爲本地JavaScript Array,此時它失去了所有的功能。所以然後我重新申請我想保留的那些(其中大部分是從hbClass繼承的)。 –

回答

1

問題可能是這一行:

this.__proto__ = Array.prototype; 

__proto__在IE瀏覽器的一些版本不支持。它已經在ES6規範中被編碼,但是在某些版本的IE中沒有實現。我不完全理解你的代碼是如何工作的,而是設置一個原型安全的方法是這樣的:

工作演示:http://jsfiddle.net/jfriend00/ff99G/

function myClass() { 
    // add new methods to this instance in the constructor 
    this.fromArray = function() {}; 
}; 
// become an array and get all its methods 
myClass.prototype = Array.prototype; 


var x = new myClass(); 

這裏是你做那種事的例子使用.prototype,在IE瀏覽器的工作原理:

function log(msg) { 
    var result = document.getElementById("result"); 
    var div = document.createElement("div"); 
    div.innerHTML = msg; 
    result.appendChild(div); 
} 

function myClass() { 
    var _push = this.push; 
    this.count = function() { 
     return this.length; 
    } 
    this.trigger = function(type, name) { 
     var str = type; 
     if (name) { 
      str += ", " + name; 
     } 
     log(str); 
    } 
    this.push = function() { 
     var retVal = _push.apply(this, arguments); 
     this.trigger("change", "push"); 
     return retVal; 
    } 
}; 

// become an array and get all its methods 
myClass.prototype = Array.prototype; 


var x = new myClass(); 

x.push("foo"); 
x.push("whatever"); 
log(x.count()); 
+0

我只是想''__proto__'。我會亂搞我的代碼,看看我是否可以用'.prototype'來代替。 –

+0

@ JamesP.Wright - 我在IE7 +中添加了一個適用於我的答案的工作演示。 – jfriend00

相關問題