Oui, c'est un problème d'initialisation. this
ne fait pas référence à votre objet SizeManager
au moment où vous l'utilisez. (Les initialiseurs d'objet ne modifient pas la valeur de this
.) this
est défini par la façon dont vous appelez une fonction et a la même valeur tout au long de cet appel de fonction. Vous n'êtes pas appelant n'importe quelle fonction, donc this
a la valeur qu'il avait avant le début de ce code.
(je l'ai signalé quelque chose ratio
de votre exemple précis à la fin de cela, mais d'abord nous allons marcher à travers quelques options pour le cas général que vous soulevez.)
Daniel's given you un bon boeuf à rendre ratio
une fonction sauf qu'il ne semble pas avoir réalisé que vous voulez faire varier la largeur. Par ailleurs, si width
et height
ne vont pas changer, calculer juste après:
var SizeManager = {
width : 800,
height : 600,
resize : function (newWidth) {
this.width = newWidth;
this.height = newWidth/this.ratio;
}
};
SizeManager.ratio = SizeManager.width/SizeManager.height;
(Side note: J'ai ajouté this.
aux propriétés que vous référencez dans resize
Ils ont été absents de votre original. ., mais ils sont nécessaires Sans eux, vous avez affaire à la horror of implicit globals, ce qui est une mauvaise chose (tm))
Bien sûr, vous pourriez résumer tout cela en une usine.
function makeSizeManager(width, height) {
return {
width : width,
height : height,
ratio : width/height,
resize : function (newWidth) {
this.width = newWidth;
this.height = newWidth/this.ratio;
}
};
}
var SizeManager = makeSizeManager(800, 600);
... mais vous pourriez aussi bien en faire une fonction constructeur réel de sorte que vous ne créez pas beaucoup de double (mais identique) resize
fonctions:
function SizeManager(width, height) {
this.width = width;
this.height = height;
this.ratio = width/height;
}
SizeManager.prototype.resize = function (newWidth) {
this.width = newWidth;
this.height = newWidth/this.ratio;
};
var aSizeManagerInstance = new SizeManager(800, 600);
(note j'ai changé les noms un peu ce dernier.)
Et comme une dernière note finale: Dans votre exemple précis, vous n'avez pas réellement besoin de stocker ratio
du tout, vous pouvez le faire:
var SizeManager = {
width : 800,
height : 600,
resize : function (newWidth) {
var ratio = this.width/this.height;
this.width = newWidth;
this.height = newWidth/ratio;
}
};
Mais ce qui est juste pour cet exemple précis, d'où la discussion ci-dessus pour parler du cas général.
Si vous passez d'un littéral d'objet à une fonction, vous devez modifier la manière dont vous spécifiez les propriétés (dans le troisième bloc de code). c'est à dire. 'this.width = width' au lieu de' this.width: width' –
@Daniel: Merci! On dirait que je n'ai modifié que partiellement ces lignes après le collage. Fixé. –