Domanda

Dato questo modello molto familiare di costruzione prototipale:

function Rectangle(w,h) {
    this.width = w;
    this.height = h;
}
Rectangle.prototype.area = function() { 
    return this.width * this.height;
};

Qualcuno può spiegare perché chiamando new Rectangle(2,3) è costantemente 10 volte più veloce di chiamare Rectangle(2,3) senza il 'nuovo' parola chiave? Avrei pensato che, poiché nuova aggiunge ulteriore complessità alla esecuzione di una funzione da ottenere prototipi coinvolti, sarebbe più lento.

Esempio:

var myTime;
function startTrack() {
    myTime = new Date();
}
function stopTrack(str) {
    var diff = new Date().getTime() - myTime.getTime();
    println(str + ' time in ms: ' + diff);
}

function trackFunction(desc, func, times) {
    var i;
    if (!times) times = 1;
    startTrack();
    for (i=0; i<times; i++) {
        func();
    }
    stopTrack('(' + times + ' times) ' + desc);
}

var TIMES = 1000000;

trackFunction('new rect classic', function() {
    new Rectangle(2,3);
}, TIMES);

trackFunction('rect classic (without new)', function() {
    Rectangle(2,3);
}, TIMES);

I rendimenti (in Chrome):

(1000000 times) new rect classic time in ms: 33
(1000000 times) rect classic (without new) time in ms: 368

(1000000 times) new rect classic time in ms: 35
(1000000 times) rect classic (without new) time in ms: 374

(1000000 times) new rect classic time in ms: 31
(1000000 times) rect classic (without new) time in ms: 368
È stato utile?

Soluzione

Quando si chiama la funzione senza "nuovo", che cosa è che si sospetta "questo" si indica? Sarà "finestra". Aggiornamento che è più lento di aggiornare il nuovo oggetto appena costruito che verrà usato quando si richiama con "nuovo".

Modificare la seconda versione di questo:

trackFunction('rect classic (without new)', function() {
    Rectangle.call({}, 2,3);
}, TIMES);

e vedere quello che si ottiene. Un'altra cosa da provare sarebbe questo:

trackFunction('rect with constant object', (function() {
  var object = { height: 0, width: 0 };
  return function() {
    Rectangle.call(object, 2, 3);
  };
})());

Che vi farà risparmiare sul costo di ricostruzione dell'oggetto manichino su ogni iterazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top