15

我读过一些关于 V8 隐藏类的文章。但是,我仍然有几个问题:

假设有两个对象:

var a = { }
a.x = 5
a.y = 6

var b = { }
b.y = 7
b.x = 8

他们最终会得到相同的隐藏班级还是仅仅因为一个去0 + x + y了另一个而分开0 + y + x?据我了解,他们有不同的课程,但只是想确保我得到它。

然后,我们有这个案例:

function Point(x, y) {
    this.x = x
    this.y = y
}
var a = new Point(7, 8)

var b = { }
b.x = 6
b.y = 8

var c = {
    x: 8,
    y: 9
}

var d = {
    y: 9,
    x: 80
}

我们最终会得到相同的隐藏类吗?我可能会猜到ab并且c做但d没有。除非对此类对象表达式进行了一些排序(类似于分析数组的短声明类型)。

最后,我们有这个:

function PointA(x, y) {
    this.x = x
    this.y = y
}
var a = new PointA(7, 8)

function PointB(x, y) {
    this.x = x
    this.y = y
}
var b = new PointB(7, 8)

这有点类似于第二种情况。这些对象看起来相同,只是它们的来源 ( instanceof...) 不同。但是,是否有对象最终具有相同的隐藏类?

4

2 回答 2

16

如果您下载 V8 并构建调试版本,您可以将这些对象随机传递给无限循环中的函数,并让它打印优化的反汇编并查看它们是否被视为具有相同的类。

在第一种情况下,您是对的,它们将具有不同的隐藏类。


在第二种情况下你错了,你最终会得到 4 个不同的类,所以它们都不共享一个类。

首先,添加到构造函数或对象字面量之外的对象的字段不会直接存储在对象上,而是存储在对象外部的数组中。所以这就是为什么b每个人都会有不同的隐藏课程。

唯一的构造函数将构造唯一类的对象,因此a每个人都会有不同的隐藏类。对象文字具有不同顺序的属性,这与第一种情况相同。

然而,具有完全相同布局的对象字面量将共享一个隐藏类,所以如果我们添加 object e

var e = {
    x: 32,
    y: -15
};

然后c将与 共享相同的隐藏类e


在第三种情况下,由于与第二种情况相同的原因,它们将具有不同的隐藏类,唯一的构造函数构造不同类的对象。


您可能还会发现这个有趣的 https://codereview.stackexchange.com/a/28360/9258

于 2013-07-24T12:50:44.550 回答
8

您可以使用 V8 的调试 shell 轻松检查d8

// test1.js
var a = { }
a.x = 5
a.y = 6

var b = { }
b.y = 7
b.x = 8

print( %HaveSameMap( a, b ) ); 

然后运行

$ d8 --allow-natives-syntax test1.js

你会得到预期的输出:

false

对于你的第二个例子:

//test2.js
function Point(x, y) {
    this.x = x
    this.y = y
}

var a = new Point(7, 8)

var b = { }
b.x = 6
b.y = 8

var c = {
    x: 8,
    y: 9
}

var d = {
    y: 9,
    x: 80
}

print( %HaveSameMap( a, b ) );
print( %HaveSameMap( b, c ) );
print( %HaveSameMap( b, d ) );
print( %HaveSameMap( c, d ) );

所有 4 个对象都有不同的隐藏类:

$ d8 --allow-natives-syntax test2.js
false
false
false
false

最后但并非最不重要:

// test3.js
function PointA(x, y) {
    this.x = x
    this.y = y
}
var a = new PointA(7, 8)

function PointB(x, y) {
    this.x = x
    this.y = y
}
var b = new PointB(7, 8)
var c = new PointB(1,4)

print( %HaveSameMap( a, b ) );
print( %HaveSameMap( b, c ) );

a并且b有不同的隐藏类,但是bc相同的。

$ d8 --allow-natives-syntax test3.js
false
true
于 2015-09-01T17:38:39.523 回答