Javascript对象文字:值初始化?

时间:2010-09-22 14:19:19

标签: javascript constructor object-literal

我正在使用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理想情况下是一个单例(只有一个对象),这就是我使用对象文字的方式。

3 个答案:

答案 0 :(得分:24)

是的,这是一个初始化问题。 this在您使用它时不会引用您的SizeManager对象。 (对象初始值设定项不会更改this的值。)this由您调用函数的方式设置,并且在整个函数调用中具有相同的值。你不是在那里调用任何函数,所以this具有该代码开头之前的任何值。

(我已经从你的具体例子中指出了ratio的一些内容,但是首先让我们来看看你提出的一般情况的几个选项。)

Daniel's given you使ratio成为一个功能的良好指导,除非他似乎没有意识到你想要改变宽度。或者,如果widthheight不会发生变化,请稍后再计算:

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)

如果您希望根据对ratiowidth的更改进行更改,则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.heightwidth而不是heightresize

答案 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;
  }
}