之前发现 js数组设置 length = 0可以清空数组。。。感觉有点蛋疼。。就想折腾下v8源码看看。。
var arr = [];
arr.push(1);
打印下arr的信息
0x32ffdb88161: [JSArray]
- map: 0x032f89a02d99 <Map(PACKED_SMI_ELEMENTS)> [FastProperties]
- prototype: 0x032f1448fea1 <JSArray[0]>
- elements: 0x032ffdb88419 <FixedArray[17]> [PACKED_SMI_ELEMENTS]
- length: 1 //长度是1
- properties: 0x032f1a480c21 <FixedArray[0]> {
#length: 0x032fb60801a9 <AccessorInfo> (const accessor descriptor)
}
- elements: 0x032ffdb88419 <FixedArray[17]> {
0: 1 //下标0对应的数据是1
1-16: 0x032f1a4805b1 <the_hole>
}
清空数组 可以 arr.length = 0;
设置length = 0之后1就都没了
0x32ffdb88161: [JSArray]
- map: 0x032f89a02d99 <Map(PACKED_SMI_ELEMENTS)> [FastProperties]
- prototype: 0x032f1448fea1 <JSArray[0]>
- elements: 0x032f1a480c21 <FixedArray[0]> [PACKED_SMI_ELEMENTS]
- length: 0
- properties: 0x032f1a480c21 <FixedArray[0]> {
#length: 0x032fb60801a9 <AccessorInfo> (const accessor descriptor)
}
通过调试得知:
之前一堆调用不管了,看调用堆栈先调用
void Accessors::ArrayLengthSetter(
v8::Local<v8::Name> name, v8::Local<v8::Value> val,
const v8::PropertyCallbackInfo<v8::Boolean>& info)
里面有一句
JSArray::SetLength(array, length);
查看该函数实现
void JSArray::SetLength(Handle<JSArray> array, uint32_t new_length) {
// We should never end in here with a pixel or external array.
DCHECK(array->AllowsSetLength());
if (array->SetLengthWouldNormalize(new_length)) {
JSObject::NormalizeElements(array);
}
array->GetElementsAccessor()->SetLength(array, new_length);
}
关键就在
array->GetElementsAccessor()->SetLength(array, new_length);
查看
SetLength(array, new_length)
void SetLength(Handle<JSArray> array, uint32_t length) final {
Subclass::SetLengthImpl(array->GetIsolate(), array, length,
handle(array->elements(), array->GetIsolate()));
}
继续查看
Subclass::SetLengthImpl
会发现
if (length == 0) {
array->initialize_elements();
}
至此 设置length = 0 为什么能清空数组算是清楚了。
再往下。。。表示我还没看懂。。是怎么初始化element的。。。应该就是要挖js-array的底层实现了。有空了继续搞