2016-07-07 4 views
5

Существует много объяснений о том, как преобразовать функцию arguments в реальный массив.Понимание методов заимствования javascript

Но я нашел это очень интересным, когда вы упрощаете код с помощью bind.

MDN Array.prototype.slice - Array-like objects

MDN Function.prototype.bind - Creating shortcuts

Например:

function list() { 
    return Array.prototype.slice.call(arguments); 
} 

var list1 = list(1, 2, 3); // [1, 2, 3] 

Упрощенный вызов:

var unboundSlice = Array.prototype.slice; 
var slice = Function.prototype.call.bind(unboundSlice); 

function list() { 
    return slice(arguments); 
} 

var list1 = list(1, 2, 3); // [1, 2, 3] 

Он работает так же, если вы используете apply вместо call:

var slice = Function.prototype.apply.bind(unboundSlice); 

Что можно даже сократить, используя call из любого экземпляра функции, так как одно и то же, как тот, в прототипе и тот же подход с slice из экземпляра массива:

var slice = alert.call.bind([].slice); 

Вы можете попробовать

var slice = alert.call.bind([].slice); 
 

 
function list() { 
 
    console.log(slice(arguments)); 
 
} 
 

 
list(1, 2, 3, 4);

Итак, первая очень странная вещь приходит мне в голову, вызывает bind на apply, но первым аргументом bind должен быть объект (как контекст), а не функция (Array.prototype.slice).

Другое, что работает с call и apply таким же образом.

Я пишу javascript довольно долгое время и используя эти методы каждый день уверенно, но я не могу обернуть вокруг себя эту голову.

Возможно, у меня отсутствуют некоторые очень фундаментальные детали.

Может ли кто-нибудь дать объяснение?

+3

Функции являются объектами. – Pointy

+0

@Pointy, спасибо, я не видел этого с этого угла. – cstuncsik

+0

* «Другое - это то, что работает с обоими вызовами и применяет то же самое». * - Потому что как 'call()', так и 'apply()' ожидать то же самое, что и их первый аргумент, и в ваших примерах вы не передадите никаких дополнительных аргументов. – nnnnnn

ответ

2

первый аргумент bind должен быть объектом (как контекст)

Да.

а не функция (Array.prototype.slice).

Почему нет? Во-первых, все функции являются объектами, поэтому здесь ничего плохого.

С другой стороны, если использовать slice.call(…) или slice.apply(…) то slice объекта является контекстом (приемник) из вызова методов call/apply.

В чем разница между переплетами apply и call?

Нет никакой разницы между applyBoundToSlice(arguments) и callBoundToSlice(arguments). Разница равна applyBoundToSlice(arguments, [0, n]) vs callBoundToSlice(arguments, 0, n), если вы хотите передать начальный и конечный аргументы в slice.

+0

Не "контекст (ресивер)", но "target (receiver)"? – Ben

+0

@BenAston: «приемник» - это технически правильный термин. Я вижу (и пишу сам) «контекст» чаще, хотя, но я почти никогда его не называю «цель» – Bergi

+0

Хорошо, ребята, теперь я понимаю. Calling bind on apply меня сбивает с толку, я думал, что я установил первый аргумент (частично применил) метода apply, но bind задает контекст как первый аргумент, и вы можете частично применить аргументы функции. @Bergi, я принимаю это как правильный ответ – cstuncsik

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