У меня возникают проблемы с обволакиванием этой функции:
var toStr = Function.prototype.call.bind( Object.prototype.toString );
toStr([]) // [object Array]
Как эта функция принимает аргумент, как показано в строке 2?
У меня возникают проблемы с обволакиванием этой функции:
var toStr = Function.prototype.call.bind( Object.prototype.toString );
toStr([]) // [object Array]
Как эта функция принимает аргумент, как показано в строке 2?
Ну,
Function.prototype.call
ссылается на функцию "вызов" , которая используется для вызова функций с выбранными значениями this
;.bind
ссылается на функцию "bind" на прототипе Function (помните: "вызов" тоже является функцией), которая возвращает новую функцию, которая всегда будет иметь this
, установленную в аргумент pass-in.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
.
Я предполагаю, что вы уже знаете, что .call
и .bind
do
toStr
теперь является функцией, которая по существу делает:
function toStr( obj ) {
return Function.prototype.call.call( Object.prototype.toString, obj );
}
I.E it .call
функция .call
с аргументом контекста, установленным в функцию .toString
. Обычно эта часть уже позаботилась, потому что вы обычно используете .call
как свойство некоторой функции, которая устанавливает функцию как контекст для .call
.
Две строки кода - это определение функции, а затем вызов выполнения этого определения с пустым массивом, переданным внутри. Сложность заключается в интерпретации того, что будет указывать '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.
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!' });
...
}
Перевод с 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 создает выделенную и не методизированную функцию только для этой цели.
Это действительно называется деметодизацией.
Вы могли бы сделать:
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.