Подтвердить что ты не робот

Как работает Function.prototype.call.bind?

У меня возникают проблемы с обволакиванием этой функции:

var toStr = Function.prototype.call.bind( Object.prototype.toString );
toStr([]) // [object Array]​​​​​​​​​​​​​​​​​​​​​​​​​​​

Как эта функция принимает аргумент, как показано в строке 2?

4b9b3361

Ответ 1

Ну,

  • Function.prototype.call ссылается на функцию "вызов" , которая используется для вызова функций с выбранными значениями this;
  • Последующая .bind ссылается на функцию "bind" на прототипе Function (помните: "вызов" тоже является функцией), которая возвращает новую функцию, которая всегда будет иметь this, установленную в аргумент pass-in.
  • Аргумент, переданный в "bind", является функцией "toString" в прототипе Object, поэтому результатом этого целого выражения является новая функция, которая будет запускать функцию "вызова" с this, установленной в "toString", функция.

Результат, таким образом, похож на этот код: Object.prototype.toString.call( param ). Затем вызов "console.log" передает эту функцию в массив, и там у вас есть.

edit Обратите внимание, что Object.prototype.toString.call( param ) действительно похож на param.toString(), когда "param" - это объект. Когда это не так, тогда семантика функции "вызов" должна превратить ее в одну в обычном порядке, как это делает JavaScript (числа → Число, строки → Строка и т.д.).

edit, 24 May2016 — Последнее предложение выше не соответствует ES2015. Новые исполняемые среды JavaScript не являются примитивными типами "autobox", когда они связаны с вызовом функции как значением this.

Ответ 2

Я предполагаю, что вы уже знаете, что .call и .bind do

toStr теперь является функцией, которая по существу делает:

function toStr( obj ) {
    return Function.prototype.call.call( Object.prototype.toString, obj );
}

I.E it .call функция .call с аргументом контекста, установленным в функцию .toString. Обычно эта часть уже позаботилась, потому что вы обычно используете .call как свойство некоторой функции, которая устанавливает функцию как контекст для .call.

Ответ 3

Две строки кода - это определение функции, а затем вызов выполнения этого определения с пустым массивом, переданным внутри. Сложность заключается в интерпретации того, что будет указывать 'this' и почему.

Чтобы помочь вывести значение этого, я скопировал контент из двух ссылок ниже в определения MDN для вызова и привязки.

Функция bind() создает новую функцию (связанную функцию) с тем же самым телом функции, что и функция, которую она вызывает on (функция целевой функции границы) с этим значением, связанным с первым аргументом bind(). Ваш код похож на "функцию быстрого доступа", описанную на странице привязки.

var unboundSlice = Array.prototype.slice; // same as "slice" in the previous example
var slice = Function.prototype.call.bind(unboundSlice);

//...

срез (аргументы);

С call вы можете назначить другой этот объект при вызове существующая функция. это относится к текущему объекту, вызывающему object.With, вы можете написать метод один раз и затем наследовать его в другой объект, без необходимости переписывать метод для нового объект.

Когда toStr вызывается, он передается в массив для привязки, из которого привязан этот указатель. С bind() это можно упростить.

toStr() is a bound function to the call() function of Function.prototype, with the this value set to the toStr() function of Array.prototype. This means that additional call() calls can be eliminated.

В сущности, это выглядит как функция shortcut переопределяет метод toString.

Ответ 4

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

Прочитайте эту документацию для получения дополнительной информации о bind() в JavaScript

Угловой пример:

Родительский компонент, где у нас есть определенная функция и она привязана к объекту:

public callback: object;

constructor() {
    this.callback= this.myFunction.bind(this);
}

public myFunction($event: any) {
    // Do something with $event ...
}

(Родительский html) передача связанного объекта дочернему компоненту:

<child-component [callbackFunction]="callback"></child-component>

Дочерний компонент, который получает объект, привязанный к родительской функции:

@Output() callbackFunction: EventEmitter<object> = new EventEmitter<object>();

public childFunction() {
    ...
    this.callbackFunction.emit({ message: 'Hello!' });
    ...
}

Ответ 5

Перевод с JS на английский -

var toStr = Function.prototype.call.bind(Object.prototype.toString);

bind создает новую функцию call Object.prototype.toString.

Теперь вы можете вызывать эту новую функцию с любым контекстом, который будет просто применен к Object.prototype.toString.

Как это:

toStr([]) // [object Array]​​​​​​​​​​​​​​​​​​​​​​​​​

Почему бы просто не вызвать Object.prototype.toString.call([])??

Ответ:

Конечно, вы могли бы. Но метод OPs создает выделенную и не методизированную функцию только для этой цели.

Это действительно называется деметодизацией.

Ответ 6

Вы могли бы сделать:

var toStr = Object.prototype.toString.call([]);

Проблема в том, что вызов выполняется мгновенно. То, что вы хотите, это отложить выполнение вызова.

* Поскольку функция также является объектом в Javascript, вы можете использовать любую функцию в качестве первого аргумента в 'call' вместо передачи объекта в качестве 1-го аргумента. * Кроме того, вы можете использовать точку при вызове, как и для любого объекта.

Function.prototype.call.bind(Object.prototype.toString) создает копию функции вызова, для которой значение this устанавливается равным Object.prototype.toString. Вы держите эту новую копию функции вызова в 'toStr'. Теперь вы можете выполнить эту новую копию вызова в любое время, когда вам нужно, без необходимости установки 'this', поскольку it 'this' уже привязано к Object.prototype.toString.