2015-12-31 2 views
0

Отметод This.apply с этим

Дугласа Crockford Javascript хорошие части

Реализации толчке

Array.method('push', function() { 
    this.splice.apply(
     this, 
     [this.lenght, 0].concat(Array.prototype.slice.apply(arquments)); 
    return this.length; 
}); 

Позволяет анализировать это с следующим примером: У меня есть массив из 10 элементов и хотите добавить следующий элемент значения 11.

Array.method('push', function() { 
    this.splice.apply(
     this, 
     [10, 0].concat([11]); 
    return this.length; 
}); 

, что дает мне

Array.method('push', function() { 
     this.splice.apply(this,[10, 0, 11]); 
     return this.length; 
    }); 

Так что я понимаю, это будет сделать это: MyInitialArray.splice (10,0,11), который будет просто найти элемент в 10 положении, не удалить ничего и добавить элемент значения 11 рядом это правильно?

Так что мой главный вопрос, почему имеет не быть конструкция с двойным этой

как: this.splice.apply (это, ... ??

вопрос предложения этого типа здесь просили, но там нет ответить на мой вопрос о двойных this.splice.apply(this

this.apply method with this as parameter

другими словами:

Если я позвоню this.splice, сращивания будет выполнять с это Allready, так почему там нужно пройти один и тот же это с применить?

+3

Поскольку вы спросили [это ранее] (http://stackoverflow.com/questions/34545772/this-applay-this) (теперь удалены) и были закрыты как дубликат вопроса, на который вы сейчас ссылаетесь, могут вы объясните, почему вы думаете, что ваш вопрос не ответил в [другом вопросе] (http://stackoverflow.com/questions/33768810/this-apply-method-with-this-as-parameter)? –

+0

Здесь нет настоящей «необходимости» для двойного 'this'. Возможно, это было '[] .splice.apply (это', но это не улучшилось бы. –

+0

@JamesThorpe, потому что это не ответ для моего поиска в возможном дубликате – kosnkov

ответ

1

Так что мой главный вопрос, почему там должен быть построено с удвоенным значением

По сути, потому что он хочет вызвать splice, предоставляя аргументы как массив, а не как дискретные аргументы.

splice ожидает дискретные аргументы и т.д .:

array.splice(1, 0, 'a', 'b', 'c'); 

... что означает "с индексом 1, удалять 0 записей, а затем добавить 'а' записей 'B' и 'с'."

Но этот код хочет вызвать splice с массивом [10, 0, 11]как будто мы сделали это:

this.splice(10, 0, 11); 

Мы не можем просто

this.splice([10, 0, 11]); // <== Doesn't work 

... потому что это просто передав массив для первого аргумента, который splice не понял бы.

Чтобы распространить массив на дискретные аргументы, в ES5 и более ранних версиях, мы должны использовать Function#apply: он вызывает функцию, которую вы вызываете apply, принимая аргументы, чтобы дать ей как массив, и вызывает эту функцию с этим массивом записи как дискретные аргументы.

Чтобы использовать Function#apply, нам нужно значение, чтобы дать ему его первый аргумент, который должен быть во время разговора this. Вот почему второй this есть.

Первый this (например, this.splice) находится именно там, поэтому мы получаем функцию splice. Эта линия также может быть:

Array.prototype.slice.apply(this, [10, 0, 11]); 
// or (can't say I like this one): 
[].slice.apply(this, [10, 0, 11]); 

Re ваш комментарий:

Если я позвоню this.splice, splice будет выполняться с this Allready, так почему там должны пройти тот же this с применить?

Этот код не непосредственно вызывающего this.splice, он звонит this.splice.apply. Первый аргумент apply - это то, что использовать как this при вызове исходной функции (this.splice).


В ES2015 (ES6), это будет сделано с распространением оператора вместо:

this.splice(...[10, 0, 11]); 

Оператор распространения распространяет записи массива из в дискретные аргументы.

+0

Вы уверены, что в этом примере this.slice - это то же самое, что [] .slice? что это фактический массив, на котором был выполнен push. Поэтому для меня больше похоже myArray.slice ([10, 0, 11]), нормально, что это не работает, поэтому myArray.slice.apply (это [10, 0, 1]), и это будет преобразовано в myArray.slice (10, 0, 1), и с вашим примером мы получим [] .slice (10,0,1), если только это не имеет значения. Slic e.apply (это, [10,0,1]) не только передаст массив в арки, но и запустит на нем срез. – kosnkov

+0

@kosnkov: Так работает прототип цепи. Выражение 'this.splice' смотрит на объект' this' ссылки для свойства 'splice' и не находит его; поэтому он смотрит на этот прототип объекта *, который также является объектом «Array.prototype». У этого объекта * есть * есть 'сращивание', так что это' сращивание', которое используется. Поэтому 'this.splice',' [] .splice' и 'Array.prototype.slice' - это все те же функции. Если бы мы вызывали его напрямую, это имело бы значение (для «этого» в вызове), как мы его просматривали, но поскольку мы используем 'apply' и явно указывая« this », это не так. –

+1

Спасибо, очень ценю это, теперь его очень ясно для меня. – kosnkov

1

Причина вы не можете просто сделать

this.splice(this.lenght, 0, someArgument) 

что push принимает переменное число аргументов, это VARIADIC. Вы можете, например, сделать

someArray.push("a", "b", "c"); 

Так подражать им, вам нужно передать массив, это цель apply. И первое this просто получить функцию splice, она могла бы быть

[].splice.apply(this, ... 

или

Array.prototype.splice.apply(this, ... 

или

var spliceFunction = Array.prototype.splice; 
spliceFunction.apply(this, ... 
+0

, но мой questin - это то, что делает «this.splice.apply (это« так, если у вас есть contex, почему причина снова применить то же самое » – kosnkov

+1

Предполагая, что вы прочитали документацию« apply »Я не понимаю, EDIT: если редактирование не дает вам понять, –

+0

, то в этом контексте Array.prototype.splice.apply (это ... это то же самое, что this.splice.apply (это ? – kosnkov

Смежные вопросы