0

基本的にネイティブ 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を除いて。
IE では、メソッドthis.arrPush.appy(this, arguments);の下の行でpush、スタック オーバーフロー エラーが発生します。
具体的には:

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;
}
4

1 に答える 1

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();

.prototypeIEで機能する、使用している種類の例を次に示します。

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());
于 2013-01-18T16:25:36.147 に答える