Зачем нам нужно применять метод внутри конструктора для вызова любого метода, определенного в объекте-прототипе?

Код рабочий:

    function Test(){
    this.x = [];
    this.add.apply(this,arguments);
    }

    Test.prototype.add = function(){
    for(var i=0; i < arguments.length; i++){
    this.x.push(arguments[i]);
    }
    }

    var t = new Test(11,12)

    t.x          //[11,12]  this is fine
    t.x.length   //2 this is also fine

Но когда я напрямую вызываю добавление внутри конструктора

Код не работает:

    function Test(){
    this.x = [];
    this.add(arguments);
    }

    Test.prototype.add = function(){
    for(var i=0; i < arguments.length; i++){
    this.x.push(arguments[i]);
    }
    }

    var t = new Test(11,12);
    t.x.length; //1 Not added all elements why?

enter image description here

1
P K 31 Дек 2012 в 16:31

1 ответ

Лучший ответ

Это не имеет ничего общего с прототипами, это связано с тем, как apply принимает массив и затем использует значения в качестве аргументов вызываемой функции. В этом случае, если вы это сделаете

this.add(arguments);

Он делает именно это. Вызов add с первым аргументом, являющимся объектом, подобным массиву, и в итоге x является массивом, где первый элемент является массивом. new Test(1, 2, 3) приведет к x = [ [1, 2, 3] ] (внутренний массив на самом деле является объектом Arguments, но похож на массив). Однако если вы это сделаете

this.add.apply(this, arguments);

По сути дела

this.add(arguments[0], arguments[1], arguments[2], ...);

Таким образом, x оказывается массивом этих элементов, а не массивом внутри массива. То есть, с new Test(1, 2, 3) вы получите x = [1, 2, 3] без дополнительного массива между ними.

5
Matti Virkkunen 31 Дек 2012 в 16:34