2013-07-24 15 views
11

Ich habe einige Artikel über versteckte Klassen von V8 gelesen. Allerdings habe ich noch ein paar Fragen in meinem Kopf haben:Das Konzept der versteckten Klassen von V8 aufräumen

Wenn, sagen wir mal, gibt es zwei Objekte:

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

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

Sie sie mit der gleichen versteckten Klasse am Ende oder trennen, nur weil man ging 0 + x + y und die andere 0 + y + x? Wie ich verstanden habe, bekommen sie verschiedene Klassen, aber ich will nur sicherstellen, dass ich sie bekommen habe.

Dann haben wir diesen Fall:

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 
} 

Haben wir mit der gleichen versteckten Klasse enden? Ich könnte vermuten, dass a, b und c tun, aber d nicht tut. Es sei denn, es wird bei solchen Objektausdrücken eine Sortierung durchgeführt (ähnlich wie bei der kurzen Erklärung des Arrays, die für den Typ analysiert wird).

Schließlich haben wir diese:

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) 

Auf dem zweiten Fall sorta ähnlich ist. Diese Objekte scheinen identisch zu sein, außer dass ihr Ursprung (instanceof...) anders ist. Gibt es jedoch Objekte mit der gleichen versteckten Klasse?

+1

Javascript hat keine Klassen. Die versteckten Klassen sind kein Konzept, sie sind interne Details der Implementierung. Es sei denn, Sie möchten v8 oder andere virtuelle Maschinen hacken, die ähnliche Probleme lösen müssen. –

+3

Ich interessiere mich eigentlich für die Leistung des Codes, den ich schreibe. Ich habe mich selbst erfahren, dass es einfacher ist, sich um Leistung * zu kümmern, als Sie * gehen, anstatt sich darum zu kümmern, wenn sich jemand beschwert, dass es zu langsam läuft. – Pijusn

+0

Es gibt Aspekte der Leistung, um die Sie sich kümmern müssen, während Sie gehen. Wie die Auswahl optimaler Algorithmen, Caching von Daten, die Sie oft benötigen und so weiter. Aber wenn Sie auf dieser Ebene wirklich auf Leistung achten müssen, sollten Sie wahrscheinlich gar nicht erst JavaScript verwenden. –

Antwort

14

Wenn Sie V8 herunterladen und die Debug-Version erstellen, können Sie diese Objekte zufällig an eine Funktion in einer unendlichen -Schleife übergeben und die optimierte Disassembly drucken lassen und sehen, ob sie als dieselbe Klasse behandelt wurden.

Im ersten Fall haben Sie recht, dass sie verschiedene versteckte Klassen haben werden.

Im zweiten Fall liegen Sie falsch, Sie werden mit 4 verschiedenen Klassen enden, also teilen keine von ihnen eine Klasse.

Zuerst werden Felder, die zu einem Objekt außerhalb von Konstruktor oder Objektliteral hinzugefügt werden, nicht direkt für das Objekt gespeichert, sondern in einem Array außerhalb des Objekts. Deshalb wird b verschiedene versteckte Klasse von allen haben.

Ein eindeutiger Konstruktor wird Objekte der eindeutigen Klasse erstellen, so dass a verschiedene versteckte Klasse von jedem haben wird. Das Objekt Literale haben Eigenschaften in unterschiedlicher Reihenfolge, was der gleiche Fall wie im ersten Fall ist.

jedoch Literale Objekt mit genau dem gleichen Layout wird eine versteckte Klasse gemeinsam nutzen, so dass, wenn wir Objekt e hinzugefügt:

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

Dann c mit e gleicher versteckter Klasse teilen würde.


Im dritten Fall, dass sie verschiedene versteckte Klassen aus dem gleichen Grunde wie im zweiten Fall, einzigartige Konstrukteuren haben Objekte verschiedener Klassen konstruieren.


könnten Sie finden auch diese interessante https://codereview.stackexchange.com/a/28360/9258

+0

Was ist die große Sache, ** die gleiche versteckte Klasse ** zu haben? Könnten Sie bitte erklären? – TrungDQ

+1

Es geht nur um die Leistung, da der Optimierer Code-Sites unterschiedlich behandelt, je nachdem, welche versteckten Klassen unterstützt werden müssen. Wenn beispielsweise in einer bestimmten Codezeile ein bestimmtes Argument immer die gleiche versteckte Klasse hat, kann der Aufruf als monomorph betrachtet werden, was [viel aggressiveres Inline-Caching] ermöglicht (http://en.wikipedia.org/wiki)/Inline_caching # Monomorphic_inline_caching) und andere Optimierungsstrategien. – Domi

5

Sie können d8 mithilfe von V8-Debugging-Shell leicht überprüfen.

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

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

print(%HaveSameMap(a, b)); 

laufen Dann

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

Sie werden die erwartete Ausgabe:

false 

Für Sie zweites Beispiel:

//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)); 

Alle 4 Objekte verschiedene versteckte Klassen :

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

Und last but not least:

// 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 und b verschiedene versteckte Klassen, aber b und c gleich.

$ d8 --allow-natives-syntax test3.js 
false 
true