Почему это изменение в прототипе Array не работает в моем плагине jQuery? - PullRequest
5 голосов
/ 29 января 2012

Я добавил следующий метод в прототип Array:

Array.prototype.foreach = function(func){
    for(var i = 0; i < this.length; i++){
        if(!func(this[i]) === false) break; //return false from func in order to break the loop
    }
    return this;
}

В том же файле, после приведенного выше кода, у меня есть следующий плагин jQuery:

jQuery.fn.addClassForEvents = function(){

    var that = this;

    arguments.foreach(function(event){
        that.bind(event[0], function(){
            that.addClass(event[0]);
        })
        .bind(event[1], function(){
            that.removeClass(event[0]);
        });
    });

    return this;
}

Чтобы использовать этот плагин jQuery, мой код должен выглядеть примерно так:

$('div').addClassForEvents(['mouseenter', 'mouseleave']);

Однако браузер выдает ошибку в строке arguments.foreach (....) плагина jQuery, указывая просто, что

У объекта # нет метода 'foreach'

Тем не менее, метод foreach работает в других местах моего кода. Почему он не определен в этом плагине jQuery?

Ответы [ 4 ]

7 голосов
/ 29 января 2012

Это не работает, потому что аргументы не являются массивом.Это (массивоподобный) объект аргументов.

Объяснение из Mozilla

Вы можете преобразовать его в массив, используя слайс в современных браузерах (и фактически выполняя цикл в IE).

var argArray = Array.prototype.slice.call(arguments)
3 голосов
/ 29 января 2012

arguments это не массив, а объект. Например, он предоставляет такие свойства, как arguments.callee и arguments.caller.

Вы можете использовать foreach прототипа Array, вызвав для него apply (ср. Объект аргументов JavaScript… и далее ):

Поскольку все методы Array.prototype разработаны как универсальные, их можно легко применить к объекту аргументов, совместимому с массивом:

jQuery.fn.addClassForEvents = function(){

    var that = this;

    [].foreach.apply(arguments, (function(event){
        that.bind(event[0], function(){
            that.addClass(event[0]);
        })
        .bind(event[1], function(){
            that.removeClass(event[0]);
        });
    });

    return this;
}
1 голос
/ 29 января 2012

Вам нужно превратить аргументы объект в массив

Попробуйте это:

jQuery.fn.addClassForEvents = function(){

    var that = this, arg = Array.prototype.slice.call(arguments);

    arg.foreach(function(event){
        that.bind(event[0], function(){
            that.addClass(event[0]);
        })
        .bind(event[1], function(){
            that.removeClass(event[0]);
        });
    });

    return this;
}
0 голосов
/ 21 июля 2016

Чтобы преобразовать arguments в массив, вы также можете использовать jQuery.makeArray(arguments) ...

http://api.jquery.com/jQuery.makeArray/

...