Да, это проблема инициализации.this
не относится к вашему SizeManager
объекту в том месте, где вы его используете.(Инициализаторы объектов не изменяют значение this
.) this
устанавливается в зависимости от того, как вы вызываете функцию, и имеет одинаковое значение в течение всего вызова этой функции.Вы не вызываете каких-либо функций, поэтому this
имеет любое значение, которое имело до начала этого кода.
(я указал кое-что о ratio
изВаш конкретный пример в самом конце этого, но сначала давайте рассмотрим несколько вариантов для общего случая, который вы подняли.)
Даниэль дал вам хорошее руководство для создания ratio
aкроме как он, кажется, не понял, что вы хотите изменить ширину.В качестве альтернативы, если width
и height
не собираются изменяться, просто рассчитайте его позже:
var SizeManager = {
width : 800,
height : 600,
resize : function (newWidth) {
this.width = newWidth;
this.height = newWidth / this.ratio;
}
};
SizeManager.ratio = SizeManager.width / SizeManager.height;
(Примечание: я добавил this.
к свойствам, на которые вы ссылаетесь вresize
. Они отсутствовали в вашем оригинале, но они необходимы. Без них вы имеете дело с ужасом неявных глобалов , который является Плохой вещью (tm) .)
Конечно, вы можете инкапсулировать все это в фабрику:
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);
... но тогда вы также можете сделать это реальной функцией конструктора, чтобы вы не• создать множество дублирующих (но идентичных) функций resize
:
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);
(Обратите внимание, что я немного изменил имена в этом последнем).
И в качестве последнего замечания:В вашем конкретном примере вам вообще не нужно хранить ratio
, вы можете сделать это:
var SizeManager = {
width : 800,
height : 600,
resize : function (newWidth) {
var ratio = this.width / this.height;
this.width = newWidth;
this.height = newWidth / ratio;
}
};
Но это только для этого конкретного примера, отсюда и обсуждение выше, чтобы поговорить об общемслучай.