所以我在 v8 中学到了一些关于隐藏类概念的知识。据说你应该声明构造函数中的所有属性(如果使用基于原型的"伪类"),并且你不应该delete
它们或在构造函数之外添加新的属性。目前为止,一切都好。
1)但是,如果您知道类型(也不应该更改)但不知道(初始)值的属性呢?
例如,做这样的事情就足够了吗:
var Foo = function () {
this.myString;
this.myNumber;
}
。并在以后分配具体值,或者最好预先分配一个"虚假"值,如下所示:
var Foo = function () {
this.myString = "";
this.myNumber = 0;
}
2)另一件事是物体。有时我只知道一个对象不会有固定的结构,但我想把它用作哈希映射。是否有任何(非冗长的)方法可以告诉编译器我想以这种方式使用它,以便它不会被优化(并在以后被取消)?
更新
感谢您的输入!因此,在阅读了您的评论(以及互联网上的更多信息)后,我认为这些要点是"最佳实践":
- 在构造函数中定义类的所有属性(也适用于定义简单对象)
- 您必须为这些属性分配一些内容,即使这只是
null
或undefined
- 仅说明this.myString;
显然是不够的 - 因为无论如何您都必须分配一些东西,所以我认为分配一个"虚假"值以防您无法立即分配最终值不会造成伤害,因此编译器确实会尽快"知道"您想要使用哪种类型。所以,例如
this.myString = "";
- 对于对象,如果您事先知道它,请分配整个结构,如果您不知道它们,请再次为其属性分配虚拟值。否则,例如,当打算将对象用作哈希映射时,只需执行:
this.myObject = {};
。认为不值得向编译器指示这应该是一个哈希图。如果你真的想这样做,我找到了一个技巧,为这个对象分配一个虚拟属性,然后立即delete
它。但我不会这样做。 - 至于较小的数组,显然建议(参考:https://www.youtube.com/watch?v=UJPdhx5zTaw&feature=youtu.be&t=25m40s)预先分配它们,特别是如果您知道最终大小,例如:
this.myArray = new Array(4);
- 以后不要
delete
属性!如果需要,只需null
它们 - 分配后不要更改类型!这将添加另一个隐藏类并损害性能。我认为无论如何,这是最佳实践。无论如何,我有不同类型的唯一情况是某些函数参数。在这种情况下,我通常会将它们转换为相同的目标类型。
- 如果以后继续添加其他属性,则同样适用。
话虽如此,我也认为这样做将倾向于更干净、更有条理的代码,并且还有助于记录。
是的,所以我不确定的一件事仍然存在:如果我在构造函数中调用的函数(例如一种configure()
方法)中定义属性怎么办?
Re 1):只是读取属性,就像在第一个代码段中一样,不会对对象执行任何操作。您需要分配它们才能创建属性。
但是对于对象属性,用什么值初始化它们实际上并不重要,只要你初始化它们。即使undefined
也应该没问题。
具体值与数组更相关,您希望确保使用正确的元素(并且没有任何孔!)创建它们,因为 VM 试图使它们保持同构。特别是,切勿使用 Array
构造函数,因为这只会创建孔。
Re 2):有一些方法可以诱使 VM 使用字典表示形式,但它们取决于 VM 和版本,并不真正可靠。通常,最好完全避免将对象用作地图。从 ES6 开始,有一个适当的 Map 类。