Bu gerçekten V8 tarafından bazı ekstra hile olduğunu. "Özellikler" JS dize endeksleri niteliklerini ise
bir JSObject
(a JS Object
iç C++ temsili), "elemanlarının" JS sayısal indisli özellikleridir iki öznitelik, elements
ve properties
sahiptir. özellik adları saklı gerekli olmadığından
Açıkçası, sayısal endeksleri, burada çok daha az bellek tüketir. Sayısal elemanları depolamak için adlandırılmış özellikleri depolanması için bir başka:
http://code.google.com/intl/de-DE/chrome/devtools/docs/memory-analysis-101.html#primitive_objects
Tipik JavaScript nesne iki diziyi posesses.
Bu
v8 kaynak kodundan görülebilir:
http://code.google.com/p/v8/source/browse/trunk/src/objects.h#1483
// [properties]: Backing storage for properties.
...
// [elements]: The elements (properties with names that are integers).
http://code.google.com/p/v8/source/browse/trunk/src/runtime.cc#4462
MaybeObject* Runtime::SetObjectProperty(Isolate* isolate,
Handle<Object> object,
Handle<Object> key,
Handle<Object> value,
PropertyAttributes attr,
StrictModeFlag strict_mode) {
...
// Check if the given key is an array index.
uint32_t index;
if (key->ToArrayIndex(&index)) {
// In Firefox/SpiderMonkey, Safari and Opera you can access the characters
// of a string using [] notation. We need to support this too in
// JavaScript.
// In the case of a String object we just need to redirect the assignment to
// the underlying string if the index is in range. Since the underlying
// string does nothing with the assignment then we can ignore such
// assignments.
if (js_object->IsStringObjectWithCharacterAt(index)) {
return *value;
}
Handle<Object> result = JSObject::SetElement(
js_object, index, value, attr, strict_mode, set_mode);
if (result.is_null()) return Failure::Exception();
return *value;
}
if (key->IsString()) {
Handle<Object> result;
if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
result = JSObject::SetElement(
js_object, index, value, attr, strict_mode, set_mode);
} else {
Handle<String> key_string = Handle<String>::cast(key);
key_string->TryFlatten();
result = JSReceiver::SetProperty(
js_object, key_string, value, attr, strict_mode);
}
if (result.is_null()) return Failure::Exception();
return *value;
}
// Call-back into JavaScript to convert the key to a string.
bool has_pending_exception = false;
Handle<Object> converted = Execution::ToString(key, &has_pending_exception);
if (has_pending_exception) return Failure::Exception();
Handle<String> name = Handle<String>::cast(converted);
if (name->AsArrayIndex(&index)) {
return js_object->SetElement(
index, *value, attr, strict_mode, true, set_mode);
} else {
return js_object->SetProperty(*name, *value, attr, strict_mode);
}
}
detaylara girmeyeceğim ama ya bu SetObjectProperty
çağrıları dikkate olmaz Tuşa bağlı olarak SetElement
veya SetProperty
. Yine de, neden test kutunuzda key = i + '0'
'un neden başarısız olduğunu bildiğinizden emin değilsiniz.