Это 24-й день моего участия в августовском испытании обновлений. Узнайте подробности события:Испытание августовского обновления.
предисловие
Function.prototype.call
Я думаю, что все чувствуют себя знакомыми,Почерк в порядке! !
Прежде чем подтвердить эту проблему, сначала посмотрите на3000 слов, и я не написал Function.prototype.call,
После прочтения вы чувствуете себя хорошо, тогда посмотрите на другой вопрос:
Пожалуйста, спросите следующий вывод
function a(){
console.log(this,'a')
};
function b(){
console.log(this,'b')
}
a.call.call(b,'b')
Если вы также четко знаете, результат, извините, босс, извините, я был неправ!
Происхождение этой статьи:
Мой друг добавил меня в WeChat и задал мне этот вопрос в приватном чате.После изучения, я снова попросил совета.апо.
Я думал, что это было интересно, поэтому я хотел поделиться им со всеми вами!
результат
Результаты таковы: Удивление или удивление, или спокойствие?
String {"b"} "b"
Взгляните на следующий код: 2, 3, 4 и более вызовов, вывод будетString {"b"} "b"
function a(){
console.log(this,'a')
};
function b(){
console.log(this,'b')
}
a.call.call(b,'b') // String {"b"} "b"
a.call.call.call(b,'b') // String {"b"} "b"
a.call.call.call.call(b,'b') // String {"b"} "b"
После прочтения вышеизложенного должно быть три вопроса?
- почему называется
b
функция - Зачем
this
даString {"b"}
- почему 2, 3, 4
call
тот же результат
В заключение:
Более двух вызовов, напримерcall.call(b, 'b')
, вы можете просто понять, что сb.call('b')
анализировать
почему 2, 3, 4call
тот же результат
a.call(b)
Последний звонокa
,
a.call.call(b)
, который в итоге называетсяa.call
a.call.call.call(b)
, который наконец выполняетсяa.call.call
Взгляните на эталонные отношения
a.call === Function.protype.call // true
a.call === a.call.call // true
a.call === a.call.call.call // true
На основании вышеизложенноговоплощать в жизньанализировать:
a.call
называетсяa
a.call.call
а такжеa.call.call.call
Разницы по сути нет, оба называютсяFunction.prototype.call
.
почему 2, 3, 4call
Результат такой же, до сих порправдаохватывать
почему называетсяb
функция
Глядя на суть, надо вернуться к оригиналу, стандарт ЕС правFuntion.prototye.callописание
Function.prototype.call (thisArg , ...args)
When the
call
method is called on an objectfunc
with argument,thisArg
and zero or moreargs
, the following steps are taken:
- If IsCallable(func) is false, throw a TypeError exception.
- Let argList be an empty List.
- If this method was called with more than one argument then in left to right order, starting with the second argument, append each argument as the last element of argList.
- Perform PrepareForTailCall().
- Return Call(func, thisArg, argList).
перевести на китайский
- Если не вызывается, сгенерируйте исключение
- Подготовьте пустую переменную массива argList
- Добавляйте переменные после первой в argList по порядку
- вернутьCall(func, thisArg, argList)результат
здесьCall
Это просто не абстрактное определение, оно находится внутри вызывающей функции.[[Call]]метод, который также не раскрывает больше полезной информации.
Собственно тут я и перестал думать:
a is a function, then what a.call.call
really do?Пояснение к статье, упомянутойBound Function Exotic Objects, МДНFunction.prototype.bindТакже упоминается:
The
bind()
function creates a new bound function, which is an exotic function object (a term from ECMAScript 2015) that wraps the original function object. Calling the bound function generally results in the execution of its wrapped function.
Function.prototype.callНаоборот, не упоминается! ! ! Но он не проверяет, генерируется ли он во время вызывающего процесса.
Difference between Function.call, Function.prototype.call, Function.prototype.call.call and Function.prototype.call.call.callЯ думаю, что объяснение более разумно.
function my(p) { console.log(p) }
Function.prototype.call.call(my, this, "Hello"); // output 'Hello'
Function.prototype.call.call(my, this, "Hello");
means:Use
my
asthis
argument (the function context) for the function that wascall
ed. In this caseFunction.prototype.call
was called.So,
Function.prototype.call
would be called withmy
as its context. Which basically means - it would be the function to be invoked.It would be called with the following arguments:
(this, "Hello")
, wherethis
is the context to be set inside the function to be called (in this case it'smy
), and the only argument to be passed is"Hello"
string.
Выделять:
So, Function.prototype.call
would be called with my
as its context. Which basically means - it would be the function to be invoked.
It would be called with the following arguments: (this, "Hello")
, where this
is the context to be set inside the function to be called (in this case it's my
), and the only argument to be passed is "Hello"
string
переводить:
Function.prototype.call.call(my, this, "Hello")
означает: использоватьmy
вызывается как контекстFunction.prototype.call
, то естьmy
это функция, которая в конечном итоге вызывается.
my
с этими(this, "Hello")
называется,this
как контекст вызываемой функции, здесь какmy
Контекст функции, единственный передаваемый параметр — это строка «hello».
Основываясь на этом понимании, давайте просто проверим, что это действительно такой внешний вид.
// case 1:
function my(p) { console.log(p) }
Function.prototype.call.call(my, this, "Hello"); // output 'Hello'
// case 2:
function a(){
console.log(this,'a')
};
function b(){
console.log(this,'b')
}
a.call.call(b,'b') // String {"b"} "b"
почему называетсяb
функция, вот правда.
На самом деле, я все еще не могу быть слишком освобожден, но это объяснение приемлемо и внешний вид правильный.Я надеюсь, что у копателей будут более разумные и подробные ответы.
Зачемthis
даString {"b"}
В анализе в предыдущем разделе я намеренно не учелFunction.prototype.call
дваnote
NOTE 1: The thisArg value is passed without modification as the this value. This is a change from Edition 3, where an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value. Even though the thisArg is passed without modification, non-strict functions still perform these transformations upon entry to the function.
NOTE 2: If
func
is an arrow function or a bound function then thethisArg
will be ignored by the function [[Call]] in step 5.
Обратите внимание на это предложение:
This is a change from Edition 3, where an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value
Два момента:
- если
thisArg
даundefined
илиnull
, будет заменен глобальным объектом
Предпосылка вот чтонестрогий режим
"use strict"
function a(m){
console.log(this, m); // undefined, 1
}
a.call(undefined, 1)
- Все остальные типы будут вызыватьToObjectдля преобразования
такнестрогий режимВниз,this
Это должен быть объект, см. следующий код:
Object('b') // String {"b"}
заметка 2ToObjectэто ответ
Вот почемуthis
даSting(b)
Это также верно
Универсальный метод вызова функции
на основеFunction.prototype.call.call
функция, мы можем инкапсулировать универсальный метод вызова функции
var call = Function.prototype.call.call.bind(Function.prototype.call);
Пример
var person = {
hello() {
console.log('hello', this.name)
}
}
call(person.hello, {"name": "tom"}) // hello tom
напиши в конце
Если вы считаете, что это хорошо, ваши лайки и комментарии — самая большая мотивация для меня двигаться дальше.
Пожалуйста, посетите группу технического обменаиди сюда. Или добавьте мое облако похорон WeChat и учитесь вместе.
Цитировать
sec-function.prototype.call
Bound Function Exotic Objects
Function.prototype.bind a is a function, then whata.call.call
really do?
Difference between Function.call, Function.prototype.call, Function.prototype.call.call and Function.prototype.call.call.call
Javascript Function.prototype.call()
Can't use Function.prototype.call directly