我正在使用object literal来创建一个带方法的对象 这是一个简单的例子。
var SizeManager = {
width : 800,
height : 600,
ratio : this.width / this.height,
resize : function (newWidth) {
width = newWidth;
height = newWidth / ratio;
}
}
我的问题是SizeManager.ratio返回“ NaN ”。我很确定这是一个初始化问题
有没有办法获得正确的比率值?
有没有办法将costructor或初始化器分配给对象文字?
是定义构造函数objcet的唯一方法吗?
编辑:关闭当然,SizeManager理想情况下是一个单例(只有一个对象),这就是我使用对象文字的方式。
答案 0 :(得分:24)
是的,这是一个初始化问题。 this
在您使用它时不会引用您的SizeManager
对象。 (对象初始值设定项不会更改this
的值。)this
由您调用函数的方式设置,并且在整个函数调用中具有相同的值。你不是在那里调用任何函数,所以this
具有该代码开头之前的任何值。
(我已经从你的具体例子中指出了ratio
的一些内容,但是首先让我们来看看你提出的一般情况的几个选项。)
Daniel's given you使ratio
成为一个功能的良好指导,除非他似乎没有意识到你想要改变宽度。或者,如果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
中引用的属性。原始版本中缺少这些属性,但它们是必需的。如果没有它们,则表示您正在处理使用horror of implicit globals,这是一件坏事(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;
}
};
但这只是针对那个具体的例子,因此上面的讨论讨论了一般情况。
答案 1 :(得分:5)
如果您希望根据对ratio
和width
的更改进行更改,则height
属性实际上应该是一种方法:
var SizeManager = {
width : 800,
height : 600,
ratio : function() {
return this.width / this.height;
},
resize : function (newWidth) {
width = newWidth;
height = newWidth / ratio;
}
}
此外,您可能希望在this.width
方法中引用this.height
和width
而不是height
和resize
。
答案 2 :(得分:0)
在对象文字中,this
仅在函数内部引用对象文字本身。你可以尝试这样的东西而不是对象文字; this
将引用您在函数内部和外部创建的对象。
var SizeManager = new function(){
this.width = 800;
this.height = 600;
this.ratio = this.width / this.height;
this.resize = function (newWidth) {
this.width = newWidth;
this.height = newWidth / this.ratio;
}
}
这适用于单身人士模式。如果需要多个SizeManager,请将其设置为构造函数而不是对象。
function SizeManager (w, h){
w && (this.width=w);
h && (this.height=h);
this.ratio = this.width / this.height;
}
SizeManager.prototype={
width: 800,
height: 600,
resize: function (newWidth) {
this.width = newWidth;
this.height = newWidth / this.ratio;
}
}