2013-07-24 5 views
11

私はV8の隠れたクラスについていくつかの記事を読んだ。しかし、私はまだ私の頭の中でいくつかの質問を持っている:V8の `隠されたクラス 'の概念をクリアする

、のは言わせた場合は、二つのオブジェクトがあります。

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

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

は、彼らが1は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 
} 

は、我々は同じ隠しクラスで終わるのですか?私は、abcはだいたい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...)が異なる以外は同じように見えます。しかし、オブジェクトは同じ隠しクラスで終わるのでしょうか?

+1

Javascriptにはクラスがありません。隠されたクラスは概念ではなく、実装の内部の詳細です。同様の問題を解決する必要があるv8やその他の仮想マシンをハックしたくない場合を除いて、気にしません。 –

+3

私は実際に私が書いたコードのパフォーマンスに心配しています。私は自分自身を経験してきました。誰かがそれをゆっくりと実行すると不平を言うときに気をつけるよりも、パフォーマンス*を気にする方が簡単です。 – Pijusn

+0

あなたが実際に気にする必要があるパフォーマンスの側面があります。最適なアルゴリズムを選ぶのと同じように、頻繁に必要なデータをキャッシュします。しかし、このレベルでのパフォーマンスを本当に気にする必要がある場合は、まずJavaScriptを使用するべきではありません。 –

答えて

14

V8をダウンロードしてデバッグバージョンをビルドすると、それらのオブジェクトを無限ループ ループ内の関数にランダムに渡して、最適化された逆アセンブリを出力し、それらが同じクラスを持つものとして扱われるかどうかを確認できます。

最初のケースでは、異なる隠されたクラスを持つことになります。


2番目のケースで間違っていると、4つの異なるクラスになります。そのため、いずれもクラスを共有しません。

最初に、コンストラクタまたはオブジェクトリテラルの外側にあるオブジェクトに追加されたフィールドは、オブジェクトの外部にある に直接格納されることはありません。だからこそ、bは誰とも異なる隠れたクラスを持つのです。

一意のコンストラクタは一意のクラスのオブジェクトを作成するため、aはすべてのユーザーとは異なる隠れたクラスを持ちます。オブジェクト リテラルは、最初のケースと同じケースで異なる順序でプロパティを持ちます。

しかし、まったく同じレイアウトを持つオブジェクトリテラルは隠されたクラスを共有しますので、我々は、オブジェクトe追加した場合:

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

を次にceと同じ隠しクラスを共有することになります。彼らは第二の場合と同様の理由のために異なる隠れクラスを有することになる第3のケースで


、独特のコンストラクタは異なるクラスのオブジェクトを構築 。


また、この興味深いhttps://codereview.stackexchange.com/a/28360/9258

+0

**同じ隠れたクラス**を持つことの大きな点は何ですか?あなたが説明してくれますか? – TrungDQ

+1

オプティマイザは、隠されたクラスをサポートする必要があるかどうかに応じて、コード・サイトを異なる方法で処理するため、すべてパフォーマンスに関するものです。たとえば、特定のコード行で、特定の引数が常に同じ隠しクラスを持つ場合、呼び出しは[より積極的なインラインキャッシング]を可能にする単相性と考えることができます(http://en.wikipedia.org/wiki/Inline_caching#Monomorphic_inline_caching)と他の最適化戦略 – Domi

5

は、あなたが簡単にV8のデバッグシェル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 

を実行します。すべての4つのオブジェクトは別の隠されたクラスを持っている

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

:あなたのための第二の例を

false 

を:

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

abが異なる隠しクラスが、bc同じを持っています。

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