var rst = 0;
var num = 0;
Array.prototype.forEach.call(num + '', function(v){ rst += +v; });

你可以从上面看到。 num
是一个数字,然后我们将其num+''
转换为字符串。控制台显示没有错误。
令我困惑的是,num
是一个字符串,为什么它可以使用forEach
方法?
答案 0 :(得分:2)
在所有符合标准的JS实现中,任何类似数组的对象都可以使用Array.prototype
中的函数,包括字符串:
var arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 }; // same as 'abc'
Array.prototype.forEach.call(arrayLike, function(val) {
console.log(val);
});
答案 1 :(得分:1)
您没有调用可能是String原型成员的forEach
函数。您明确调用Array
原型forEach
并告诉它将thisArg
视为Array
。根据您的运行时环境,forEach
的实现可能取决于浏览器/环境,但最坏的情况是它什么都不做,并默默地返回undefined
。
这是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());
}