2010-11-11 22 views

Répondre

5

Il n'est pas possible de référencer "this" dans une expression spécifiant un littéral d'objet. Soit le faire dans une ligne suivante ou utilisez un constructeur comme celui-ci:

function myobj(a,b) { 
    this.a = a; 
    this.b = b; 
    this.c = this.a + this.b; 
} 

var test = new myobj(10,20); 

En réponse à la méthode est plus rapide, la création avec le constructeur de l'objet est plus rapide. Voici une comparaison de cas de test simple. Run it yourself on JSBIN.

Les résultats montrent que la création d'un objet avec un constructeur vs un littéral d'objet est presque deux fois plus vite:

0.450s: testObjectLiteral

0.506s: testObjectLiteralWithFunction

0.280s: testConstructor

Voici le code de test incorporé:

// timer function 
function time(scope){ 
    time.scope = time.scope || {}; 
    if(time.scope[scope]) { 
    var duration = (new Date()).getTime()-time.scope[scope]; 
    time.scope[scope] = null; 
    var results = document.getElementById("results"); 
    results.innerHTML = results.innerHTML + '<p>'+(duration/1000).toFixed(3)+'s : '+scope+'</p>'; 
    } else { 
    time.scope[scope] = (new Date()).getTime(); 
    } 
} 

// object creation function with constructor 
function myobj(a,b) { 
    this.a = a; 
    this.b = b; 
    this.c = this.a + this.b; 
} 

function testConstructor(iterations) { 
    var objs = new Array(iterations); 
    for(i=0;i<iterations;i++) { 
    objs[i] = new myobj(i,i+1); 
    } 
    return objs; 
} 

function testObjectLiteralWithFunction(iterations) { 
    var objs = new Array(iterations); 
    for(i=0;i<iterations;i++) { 
    objs[i] = { 
     a: i, 
     b: i+1, 
     c: function() { 
     return this.a + this.b; 
     } 
    }; 
    } 
    return objs; 
} 


function testObjectLiteral(iterations) { 
    var objs = new Array(iterations); 
    for(i=0;i<iterations;i++) { 
    var item = { 
     a: i, 
     b: i+1 
    }; 
    item.c = item.a + item.b; 
    objs[i] = item; 
    } 
    return objs; 
} 

var ITERATIONS = 1000000; 
time("testObjectLiteral"); 
testObjectLiteral(ITERATIONS); 
time("testObjectLiteral"); 

time("testObjectLiteralWithFunction"); 
testObjectLiteralWithFunction(ITERATIONS); 
time("testObjectLiteralWithFunction"); 

time("testConstructor"); 
testConstructor(ITERATIONS); 
time("testConstructor"); 

+0

+1 pour la solution OOP. – zzzzBov

+0

Merci pour votre aide. Une autre question: est-ce une façon de déclarer un objet plus vite que le "var myObj = {a: 4, b: 5 ....};" un? –

+0

@dizzy_fingers voir le cas de test de performance J'ai ajouté à ma réponse – mbrevoort

2

Ce n'est pas possible dans un littéral d'objet puisque this ne peut pas faire référence à un objet qui n'a pas encore été créé. Votre meilleure option est d'attribuer la propriété c dans une étape séparée:

var test = { 
    a: 10, 
    b: 20 
}; 

test.c = test.a + test.b; 
0

Vous pouvez tout simplement pas le faire lors de la déclaration d'un objet littéral, le plus proche que vous pouvez faire est:

var test = { 
    a: 10, 
    b: 20 
}; 
test.c = test.a + test.b; 

Dans votre contexte this fait référence à tout ce contexte parent, vous êtes, pas l'objet test ... et même si elle l'a fait, vous ne pouvez pas déclarer les membres comme, par exemple, cela est également invalide:

var test = { a: 10, b: 20, test.c: test.a + test.b }; 

... car test, a et b ne sont pas encore définis, car il s'agit d'une instruction unique qui n'est pas terminée.

-2

Pourquoi ne pas faire c une fonction pour qu'elle retourne toujours la valeur actuelle d'un + b?

var test = { 
    a: 5, 
    b: 1, 
    c: function() { 
     return this.a + this.b; 
    } 
} 
+0

Nous vous remercions de votre suggestion. Mais qu'en est-il des problèmes de performance? L'ajout d'une fermeture après la déclaration c: un surcoût supplémentaire? –

+0

Eh bien, j'imagine que - à chaque fois que c() est appelé, il évalue a + b, plutôt que de simplement récupérer la valeur d'une variable. Cependant, selon votre situation, cette différence peut être négligeable.Si l'opération d'addition implique un nombre significatif de valeurs, et/ou que vous faites référence à c() un nombre important de fois, il peut être préférable de ne faire ce calcul qu'une fois à l'initialisation, auquel cas la solution de mbrevoort ci-dessous peut être plus utile. En fin de compte, cela se résume à votre situation et si oui ou non a/b va changer pendant l'exécution. –

+0

-1 est cette réponse correcte ??? – gath