我有一个基本上是原生Javascript数组的类,但是在添加或删除项时会引发事件。
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中
在this.arrPush.appy(this, arguments);
方法下的push
行的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 :(得分:1)
问题可能就在这一行:
this.__proto__ = Array.prototype;
某些版本的IE不支持__proto__
。它已在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();
以下是您使用在IE中运行的.prototype
所做的事情的示例:
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());