Что call.call выполняет в JavaScript - PullRequest
4 голосов
/ 09 февраля 2012

Нашел этот отрывок в исходном коде Modernizr.

var documentCreateElement = scopeDocument.createElement, documentCreateDocumentFragment = scopeDocument.createDocumentFragment;

// shiv the document
for (var i = 0, elements = html5.elements, l = elements.length; i < l; ++i) {
     call.call(documentCreateElement, scopeDocument, elements[i]);
}

// shiv the document create element method
scopeDocument.createElement = function (nodeName) {
var element = call.call(documentCreateElement, scopeDocument, nodeName);

Мне было интересно, почему было необходимо использовать call.call, а не просто call Что является достижением, которого нет documentCreateElement.call(scopeDocument,nodeName)?

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 09 февраля 2012

call.call вызывает пользовательскую функцию call с другим контекстом .

call - встроенная функция JavaScript.Это функция, которую вы можете вызвать для функции, потому что в JavaScript функции граждане первого класса , и она называется call, что очень запутанно: P

Первый параметр call это контекст , на что this должен ссылаться в вызываемой функции.Вот пример:

function doit() {
    console.log(this.myvalue);
}

function callit(context) {
    doit.call(context);
}

callit({ "myvalue": "a value"});    // a value
var obj = {
    "stuff" : "more stuff",
    "myvalue": "some value"
};
callit(obj);    // some value

Так что documentCreateElement.call(scopeDocument,nodeName) в основном делает documentCreateElement(nodeName), но this в documentCreateElement указывает на scopeDocument.Вы можете задаться вопросом, является ли приведенный вами пример кода правильным использованием call.Я всегда нахожу это очень сложным, если используется неправильно и неуместно ~ _ ~

1 голос
/ 09 февраля 2012

Да, она вызывает функцию .call из контекста функции documentCreateElement.

Так что в конечном итоге это то же самое, что и ...

documentCreateElement.call(scopeDocument, nodeName);

Я предполагаю, что естьссылка на Function.prototype.call где-то, например

var call = Function.prototype.call

Они, вероятно, кэшируют метод call на тот случай, если он будет перезаписан на Function.prototype.


РЕДАКТИРОВАТЬ:

Как указано @ ruakh ниже, если Function.prototype.call было перезаписано, то call.call не будет работатьпоскольку он также основан на Function.prototype.

documentCreateElement - это ссылка на метод document.createElement, а этот метод является хост-объектом, поэтому нет гарантии, что он включит Function.prototype в свой прототипchain.

Это позволит им использовать .call в хост-объектах в этих случаях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...