2016-01-21 2 views
8

enter image description herea - функция, то что делает `a.call.call` действительно?

Эти коды выполняются на chrome devtool.

Похоже, что b.call (то же самое, что и a.call.call) вызывает первый аргумент, который является функцией, а затем передает второй аргумент как this. Если первый аргумент не является функцией, тогда выполните ошибку not a function.

Может кто-нибудь объяснить, как работает <Function>.call.call?

+0

«[Военачальники документации] (http://meta.stackoverflow.com/q/303865/419956)« a.k.a. «NullReference» еще не существует, до тех пор ваш вопрос, вероятно, слишком широк. До тех пор я бы рекомендовал другие ресурсы, такие как [MDN] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/call). – Jeroen

+0

@jeroen Я уже читал, что doc на MDN, но это только объясняет, как работает функция 'call', и приводятся некоторые примеры. То, что я точно спрашиваю здесь, это 'call.call', поведение которого отличается от' call'. И я не могу получить работу за «call.call». – tjfdfs

+1

Первый аргумент '.call()' - это объект, который вы хотите установить как значение 'this' в функции, для которой' call() 'должен работать. Если 'call()' сама является функцией, которой нужно управлять, потому что вы привязали '.call.call()', что она делает с предоставленным значением 'this'? Он предполагает, что это функция и пытается ее называть. Но ваша последняя строка кода не передает функцию, она передает пустой объект. – nnnnnn

ответ

8

Позвольте мне показать вам пример.

function a() { console.log(1) } 

function b() { console.log(2) } 

a.call(b) // 1 

a.call.call(b) // 2 

a.call.call.call(b) // 2 

Почему?

Мы знаем a.call(b) средство вызова a() с это значение b.

Так что a.call.call(b) средство вызова Function.prototype.call() с это значение б, так же, как Function.prototype.call.call(b).

Но Function.prototype.call.call() не является обычной функцией. Он может быть вызван, но у него нет свойства. Есть некоторые уникальные правила, чтобы вызвать его.

Function.prototype.call.call(a) // 1 

Function.prototype.call.call(b) // 2 

В самом деле, это Function.prototype.call.call(b) экзотический объект, кроме того, граница функции экзотического объекта.

  • [Спецификация] Связанная функция - это экзотический объект, который обертывает другой объект функции.

  • [Спецификация] Вызов связанной функции обычно приводит к вызову его завернутой функции.

Так что Function.prototype.call.call(a) просто означает a().

a.call.call(x) означает invoke x, то есть x().

  • [Спецификация] В Function.prototype.call(thisArg), если thisArg не определен или нулевой, то он будет заменен на глобальный объект.

a.call.call() означает a.call.call(undefined) означает a.call.call(window) средство вызова window.

Попробуйте вызвать window вы получите Uncaught TypeError: window is not a function, поэтому постарайтесь вызвать a.call.call() вы получите Uncaught TypeError: a.call.call is not a function.

Надеюсь, это поможет.

1

Начиная от основного материала,

Что такое .call? его функция доступна внутри Function.prototype. Чтобы его можно было вызвать на любую функцию, именно поэтому вы можете позвонить a.call.

Теперь, что делает .call? он устанавливает this контекст функции, которую вы назвали .call. поэтому в вашем случае, когда вы вызываете a.call, он может установить контекст this на функцию a (через первый параметр, который вы передаете функции .call).

что такое this внутри .call функция? это не что иное, как функции вы назвали .call на (в вашем случае a)
так для простоты вы предполагаете, внутри .call может быть вызовом функции, как this() (и что нет ничего, кроме вызова a()) - до сих пор так хороший

на ваш вопрос

a.call.call 

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

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

Надеюсь, я мог бы объяснить, что я хотел объяснить.

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

в вас дело .call.call должны были призваны на Function.prototype или Object или любой другой функции (помните .call является частью Function.prototype и может быть вызван любой функции)

так что вы должны были сделать

Function.prototype.call.call(...) 

или даже

Object.call.call(...) 

Теперь я был смущен о них вещи на прошлой неделе (не .call.call но .call.bind), я задал вопрос здесь, и кто-то объяснил мне очень подробно, вы можете найти его HERE

Я попытался ответить из своего понимания из вопроса, который я задал.

после того, как все это то, что SO для

UPDATE:

вас вопрос «Похоже, что b.call (такой же, как a.call.call) звонит первый аргумент, который функцию, затем передайте второй аргумент как это.Если первый аргумент не является функцией, то бросайте не ошибку функции. "

ваше предположение верно здесь

+0

спасибо! Я прочитаю ваш ответ и ссылки дважды, чтобы получить некоторые идеи. – tjfdfs

+0

и ваше предположение верно, и я обновил свой ответ, чтобы зафиксировать это. – Oxi

+0

Просьба рассказать об этом с примером, который будет легко понять. –