Javascript 为什么字符串变量可以在JS中通过调用使用forEach方法?

Javascript 为什么字符串变量可以在JS中通过调用使用forEach方法?,javascript,Javascript,var-rst=0; var num=0; 调用(num+'',函数(v){rst+=+v;})您没有调用可能是字符串原型成员的forEach函数。您正在显式调用数组原型forEach,并告诉它将thisArg视为数组。根据您的运行时环境,forEach的实现可能依赖于浏览器/环境,但在最坏的情况下,它将什么也不做,并以静默方式返回未定义的 这里有一些来自webkit的资料。有一些特定于数组的代码,但一般来说,它没有理由不适用于任何东西 EncodedJSValue JSC_HOST_CALL

var-rst=0;
var num=0;

调用(num+'',函数(v){rst+=+v;})您没有调用可能是字符串原型成员的
forEach
函数。您正在显式调用
数组
原型
forEach
,并告诉它将
thisArg
视为
数组
。根据您的运行时环境,
forEach
的实现可能依赖于浏览器/环境,但在最坏的情况下,它将什么也不做,并以静默方式返回
未定义的

这里有一些来自webkit的资料。有一些特定于数组的代码,但一般来说,它没有理由不适用于任何东西

EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
{
    JSObject* thisObj = exec->hostThisValue().toObject(exec);
    unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
    if (exec->hadException())
        return JSValue::encode(jsUndefined());

    JSValue function = exec->argument(0);
    CallData callData;
    CallType callType = getCallData(function, callData);
    if (callType == CallTypeNone)
        return throwVMTypeError(exec);

    JSValue applyThis = exec->argument(1);

    unsigned k = 0;
    if (callType == CallTypeJS && isJSArray(thisObj)) {
        JSFunction* f = jsCast<JSFunction*>(function);
        JSArray* array = asArray(thisObj);
        CachedCall cachedCall(exec, f, 3);
        for (; k < length && !exec->hadException(); ++k) {
            if (UNLIKELY(!array->canGetIndexQuickly(k)))
                break;

            cachedCall.setThis(applyThis);
            cachedCall.setArgument(0, array->getIndexQuickly(k));
            cachedCall.setArgument(1, jsNumber(k));
            cachedCall.setArgument(2, thisObj);

            cachedCall.call();
        }
    }
    for (; k < length && !exec->hadException(); ++k) {
        PropertySlot slot(thisObj);
        if (!thisObj->getPropertySlot(exec, k, slot))
            continue;

        MarkedArgumentBuffer eachArguments;
        eachArguments.append(slot.getValue(exec, k));
        eachArguments.append(jsNumber(k));
        eachArguments.append(thisObj);

        if (exec->hadException())
            return JSValue::encode(jsUndefined());

        call(exec, function, callType, callData, applyThis, eachArguments);
    }
    return JSValue::encode(jsUndefined());
}
EncodedJSValue JSC\u HOST\u调用arrayProtoFuncForEach(ExecState*exec)
{
JSObject*thisObj=exec->hostThisValue().toObject(exec);
unsigned length=thisObj->get(exec,exec->propertyNames().length).toUInt32(exec);
如果(exec->hadException())
返回JSValue::encode(jsUndefined());
JSValue function=exec->argument(0);
CallData CallData;
CallType CallType=getCallData(函数,callData);
if(callType==CallTypeNone)
返回throwVMTypeError(exec);
JSValue applyThis=exec->argument(1);
无符号k=0;
if(callType==CallTypeJS&&isJSArray(thisObj)){
JSFunction*f=jsCast(函数);
JSArray*array=asArray(thisObj);
CachedCall CachedCall(exec,f,3);
对于(;khadException();++k){
if(不太可能(!array->cangetIndex(k)))
打破
cachedCall.setThis(applyThis);
setArgument(0,数组->getIndexQuick(k));
setArgument(1,jsNumber(k));
cachedCall.setArgument(2,thisObj);
cachedCall.call();
}
}
对于(;khadException();++k){
地产地块插槽(thisObj);
如果(!thisObj->getPropertySlot(exec,k,slot))
继续;
标记argumentbuffereacharguments;
append(slot.getValue(exec,k));
append(jsNumber(k));
附加(thisObj);
如果(exec->hadException())
返回JSValue::encode(jsUndefined());
调用(exec、function、callType、callData、applyThis、eachArguments);
}
返回JSValue::encode(jsUndefined());
}

您没有调用可能是字符串原型成员的
forEach
函数。您正在显式调用
数组
原型
forEach
,并告诉它将
thisArg
视为
数组
。根据您的运行时环境,
forEach
的实现可能依赖于浏览器/环境,但在最坏的情况下,它将什么也不做,并以静默方式返回
未定义的

这里有一些来自webkit的资料。有一些特定于数组的代码,但一般来说,它没有理由不适用于任何东西

EncodedJSValue JSC_HOST_CALL arrayProtoFuncForEach(ExecState* exec)
{
    JSObject* thisObj = exec->hostThisValue().toObject(exec);
    unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
    if (exec->hadException())
        return JSValue::encode(jsUndefined());

    JSValue function = exec->argument(0);
    CallData callData;
    CallType callType = getCallData(function, callData);
    if (callType == CallTypeNone)
        return throwVMTypeError(exec);

    JSValue applyThis = exec->argument(1);

    unsigned k = 0;
    if (callType == CallTypeJS && isJSArray(thisObj)) {
        JSFunction* f = jsCast<JSFunction*>(function);
        JSArray* array = asArray(thisObj);
        CachedCall cachedCall(exec, f, 3);
        for (; k < length && !exec->hadException(); ++k) {
            if (UNLIKELY(!array->canGetIndexQuickly(k)))
                break;

            cachedCall.setThis(applyThis);
            cachedCall.setArgument(0, array->getIndexQuickly(k));
            cachedCall.setArgument(1, jsNumber(k));
            cachedCall.setArgument(2, thisObj);

            cachedCall.call();
        }
    }
    for (; k < length && !exec->hadException(); ++k) {
        PropertySlot slot(thisObj);
        if (!thisObj->getPropertySlot(exec, k, slot))
            continue;

        MarkedArgumentBuffer eachArguments;
        eachArguments.append(slot.getValue(exec, k));
        eachArguments.append(jsNumber(k));
        eachArguments.append(thisObj);

        if (exec->hadException())
            return JSValue::encode(jsUndefined());

        call(exec, function, callType, callData, applyThis, eachArguments);
    }
    return JSValue::encode(jsUndefined());
}
EncodedJSValue JSC\u HOST\u调用arrayProtoFuncForEach(ExecState*exec)
{
JSObject*thisObj=exec->hostThisValue().toObject(exec);
unsigned length=thisObj->get(exec,exec->propertyNames().length).toUInt32(exec);
如果(exec->hadException())
返回JSValue::encode(jsUndefined());
JSValue function=exec->argument(0);
CallData CallData;
CallType CallType=getCallData(函数,callData);
if(callType==CallTypeNone)
返回throwVMTypeError(exec);
JSValue applyThis=exec->argument(1);
无符号k=0;
if(callType==CallTypeJS&&isJSArray(thisObj)){
JSFunction*f=jsCast(函数);
JSArray*array=asArray(thisObj);
CachedCall CachedCall(exec,f,3);
对于(;khadException();++k){
if(不太可能(!array->cangetIndex(k)))
打破
cachedCall.setThis(applyThis);
setArgument(0,数组->getIndexQuick(k));
setArgument(1,jsNumber(k));
cachedCall.setArgument(2,thisObj);
cachedCall.call();
}
}
对于(;khadException();++k){
地产地块插槽(thisObj);
如果(!thisObj->getPropertySlot(exec,k,slot))
继续;
标记argumentbuffereacharguments;
append(slot.getValue(exec,k));
append(jsNumber(k));
附加(thisObj);
如果(exec->hadException())
返回JSValue::encode(jsUndefined());
调用(exec、function、callType、callData、applyThis、eachArguments);
}
返回JSValue::encode(jsUndefined());
}

在所有符合标准的JS实现中,任何类似数组的对象都可以使用
数组中的函数。prototype
,包括字符串:

var arrayLike={0:a',1:b',2:c',长度:3};//与“abc”相同
Array.prototype.forEach.call(类arrayLike,函数(val){
控制台日志(val);

});在所有符合标准的JS实现中,任何类似数组的对象都可以使用
数组中的函数。prototype
,包括字符串:

var arrayLike={0:a',1:b',2:c',长度:3};//与“abc”相同
Array.prototype.forEach.call(类arrayLike,函数(val){
控制台日志(val);

});“它的实现将依赖于浏览器/环境”-在哪个部分?
Array.prototype.forEach
的行为非常标准化。“它可能只是默默地返回未定义的”-否,因为
.forEach()
设计用于通过
.call()
.apply()
调用类似数组的对象(包括字符串)。显示的代码可以正常工作。@zerkms是的,
Array.prototype.forEach的API和行为是标准的,但实际的实现不是。@zerkms-Fro