我读过一些关于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
}
我们最终会使用相同的隐藏类吗?我猜可能会a
,b
和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...
)不同之外,这些对象看起来是一样的。但是,那些对象最终会使用相同的隐藏类吗?
答案 0 :(得分:15)
如果您下载V8并构建调试版本,则可以将这些对象随机传递给无限的函数 循环并让它打印优化的反汇编,看看它们是否被视为具有相同的类。
在第一种情况下,你是对的,他们会有不同的隐藏类。
在第二种情况下,你错了,你最终会得到4个不同的类,所以没有一个人共享一个类。
首先,添加到构造函数或对象文字外部的对象的字段不会直接存储
在对象上,但在对象外部的数组中。这就是为什么b
将拥有与所有人不同的隐藏类。
唯一的构造函数将构造唯一类的对象,因此a
将拥有与每个人不同的隐藏类。物体
文字具有不同顺序的属性,与第一种情况的情况相同。
然而,具有完全相同布局的对象文字将共享一个隐藏类,因此如果我们添加了对象e
:
var e = {
x: 32,
y: -15
};
然后c
会与e
分享相同的隐藏课程。
在第三种情况下,它们将具有不同的隐藏类,其原因与第二种情况中的唯一构造函数相同 构建不同类的对象。
您可能还会发现这个有趣的https://codereview.stackexchange.com/a/28360/9258
答案 1 :(得分:7)
您可以使用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
有不同的隐藏类,但b
和c
相同。
$ d8 --allow-natives-syntax test3.js
false
true