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

Where Call and Apply functions are defined in javascript

请允许我知道Java脚本中调用和应用函数的定义。最初我以为它们是在function.prototype对象中定义的,所以所有函数都从那里继承它们。但是当我执行function.prototype(在crome控制台中)时,它会给我提供函数empty()。

有人能告诉我这些函数来自哪里,为什么function.prototype指向空方法吗?

事先谢谢。


你看到了正确的行为。规范第15.4.3节规定:

The Function prototype object is
itself a Function object (its
[[Class]] is"Function") that, when
invoked, accepts any arguments and
returns undefined.

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

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

提示:默认情况下,chrome输出函数为字符串(Function.prototype.toString)。您可以使用console.dir强制它显示对象树的所有属性:

1
console.dir(Function.prototype);


这是webkit中javascriptcore(nitro)的Function.prototype.apply的源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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源以找到它们的实现。我自己找不到。如果有人想指点我的来源,那就太酷了。)


尝试

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

您没有看到它们的原因是因为内置的对象属性/函数通常是不可枚举的。Object.getOwnPropertyNames是一个函数,设计用于列出对象的属性,而不考虑可枚举性。它也是emcascript 5规范中最近添加的一个,但是chrome应该很好地支持它。