call.call在javascript中完成了什么

时间:2012-02-08 22:33:12

标签: javascript modernizr

在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 个答案:

答案 0 :(得分:1)

是的,它从.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

这将允许他们在这些情况下对宿主对象使用.call

答案 1 :(得分:1)

call.call使用不同的上下文调用用户定义的函数call

call是本机JavaScript函数。它是一个可以调用函数的函数,因为在JavaScript函数中是一等公民,它被称为call,这非常令人困惑:P

call的第一个参数是 context ,无论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。如果错误使用并且不合适,我总觉得它非常复杂~~~