Почему вызов Function.apply.bind (fn, null) вызывает `fn.apply`, а не` Function.apply`? - PullRequest
0 голосов
/ 22 сентября 2018

Предположим, у нас есть этот код:

let fn1 = Function.apply.bind(Math.max, null);
fn1([1, 10, 5]); // returns 10

Я знаю, что это spread function в ES6, мы вместо этого написали бы:

Math.max(...[1, 10, 5]);

Но я не могу понять, как Function.apply.bind делает свое волшебство ...

Вот как я думаю, что код работает, пожалуйста, исправьте меня, где я ошибаюсь.

  1. Это утверждение let fn1 = Function.apply.bind(Math.max, null); создает новую функцию Function.apply(null)с this, установленным на Math.max, и назначает его переменной fn1.
  2. Этот оператор fn1([1, 10, 5]); вызывает нашу вновь созданную функцию следующим образом: Function.apply(null, [1, 10, 5]) с this внутри этой функции установлено значение Math.max.Но этот вызов недействителен ... если мы скопируем / вставим эту строку в консоль JS - мы получим Uncaught SyntaxError: Unexpected number

Итак, мой вопрос - как Function.apply знает, что он должен использовать this равно Math.max и "повернуть" / изменить его вызов на Math.max.apply?

Обновлено

Я только что понял, как все это работает!Во-первых, давайте перепишем код в его «реальную» форму:

let fn1 = this.Function.apply.bind(Math.max, null);
this.fn1([1, 10, 5]); // returns 10

Magic?this неявно добавляется к «глобальным» методам / объектам.Теперь давайте перепишем эти 2 абзаца текста, чтобы показать вам, как работает магия:)

  1. Этот оператор let fn1 = Function.apply.bind(Math.max, null); создает новую функцию newFunction.apply(null, ...args), где newFunction == Math.max, так что она такая же, как функцияMath.max.apply(null, ...args) и присваивает его переменной fn1.
  2. Этот оператор fn1([1, 10, 5]); вызывает newFunction.apply(null, [1, 10, 5])

Магия раскрыта:)

Дублирующее обновление

Этот вопрос не является дубликатом другого вопроса.Это отличается, потому что это более конкретно, здесь я спрашиваю конкретно: «Почему вызов Function.apply.bind (fn, null) вызывает fn.apply, а не Function.apply?»а не «Как работает apply.bind?».Это все равно что сказать, что вопрос «Почему велосипедные механизмы используют кинестетическую силу педалей, а не генерируют силу непосредственно при ускорении?»так же, как вопрос "Как работает велосипед?"

Ответы [ 2 ]

0 голосов
/ 22 сентября 2018

Давайте разделим его на части, прежде всего, bind():

Метод bind () создает новую функцию, которая, когдаcall, имеет ключевое слово this, установленное на указанное значение, с заданной последовательностью аргументов, предшествующей любому предоставленному при вызове новой функции.

Итак, вы bind applyметод из Function глобального объекта в Math.max.

Функция fn1, возвращаемая bind(), поэтому эквивалентна this.apply(), где this на самом деле Math.max, точно так же, как выспросил "к bind() методу.

0 голосов
/ 22 сентября 2018

Эта строка:

let fn1 = Function.apply.bind(Math.max, null);

... действительно сложно.:-) Он вызывает bind на Function.apply, создавая функцию, которая будет вызывать apply с Math.max в качестве значения this и null в качестве первого аргумента ( thisArg , которыйapply следует использовать при вызове Math.max; Math.max не заботится о this, поэтому null в порядке).

Когда вы звоните fn1, он вызывает Function.apply сthis устанавливается в Math.max и null в качестве первого аргумента, за которым следует массив, который вы передаете в fn1.apply вызывает Math.max с null как this и записи из массива как дискретные аргументы.

...