其中Call和Apply函数在javascript中定义

时间:2011-04-11 22:10:14

标签: javascript

有人可以告诉我java脚本中定义了call和apply函数的位置。 最初我认为它们是在Function.prototype对象中定义的,为什么所有函数都从那里继承它们。但是当我执行Function.prototype时(在Crome控制台中)它给我函数Empty(){}。

有人可以告诉我这些功能的来源以及为什么Function.prototype指向空方法。

提前致谢。

3 个答案:

答案 0 :(得分:1)

你看到了正确的行为。 The specification,第15.4.3节说:

  

函数原型对象是   本身就是一个Function对象(它的   [[Class]]是“Function”),当   调用,接受任何参数和   返回undefined。

所有函数都是JS中的对象,虽然Function.prototype实际上是函数本身并不是callapply不能从该对象继承的原因。

如果您在第15.4.3节中进一步阅读,则会看到applycallFunction.prototype的成员。

提示:Chrome默认情况下将函数输出为字符串(Function.prototype.toString)。您可以使用console.dir

强制它显示所有属性 - 对象树
console.dir(Function.prototype);

答案 1 :(得分:0)

尝试

Object.getOwnPropertyNames(Function.prototype);
//["bind", "arguments", "toString", "length", "call", "name", "apply", "caller", "constructor"]

您没有看到它们的原因是因为内置对象属性/功能通常是不可枚举Object.getOwnPropertyNames是一个用于列出对象属性的函数,无论可枚举性如何。它也是EMCAScript 5规范附带的最新版本,但Chrome应该支持它。

答案 2 :(得分:0)

以下是来自WebKit中的JavaScriptCore(Nitro)的Function.prototype.apply的源代码

EncodedJSValue JSC_HOST_CALL functionProtoFuncApply(ExecState * exec) {
    JSValue thisValue = exec - > hostThisValue();
    CallData callData;
    CallType callType = getCallData(thisValue, callData);
    if (callType == CallTypeNone) return throwVMTypeError(exec);

    JSValue array = exec - > argument(1);

    MarkedArgumentBuffer applyArgs;
    if (!array.isUndefinedOrNull()) {
        if (!array.isObject()) return throwVMTypeError(exec);
        if (asObject(array) - > classInfo() == & Arguments::s_info) asArguments(array) - > fillArgList(exec, applyArgs);
        else if (isJSArray( & exec - > globalData(), array)) asArray(array) - > fillArgList(exec, applyArgs);
        else if (asObject(array) - > inherits( & JSArray::s_info)) {
            unsigned length = asArray(array) - > get(exec, exec - > propertyNames().length).toUInt32(exec);
            for (unsigned i = 0; i < length; ++i)
            applyArgs.append(asArray(array) - > get(exec, i));
        } else return throwVMTypeError(exec);
    }

    return JSValue::encode(call(exec, thisValue, callType, callData, exec - > argument(0), applyArgs));
}

如果您愿意,可以通过V8和JaegerMonkey源查找其实现。我自己找不到它们。如果有人想指出我或那些那些很酷的那些:)