Javascript 对象字面量:值初始化?

发布于 2024-09-25 02:58:06 字数 467 浏览 5 评论 0 原文

我正在使用对象文字来创建带有方法的对象。
这是一个简单的例子。

var SizeManager = {
    width : 800,
    height : 600,
    ratio : this.width / this.height,
    resize : function (newWidth) {
        width = newWidth;
        height = newWidth / ratio;
    }
}

我的问题是 SizeManager.ratio 返回“NaN”。我很确定这是一个初始化问题。
有没有办法获得正确的比率值?
有没有办法将构造函数或初始值设定项分配给对象文字?
定义构造函数对象是唯一的方法吗?

编辑:当然 SizeManager 理想情况下是一个单例(只有一个对象),这就是我使用对象文字的方式。

i was using object literal to create an object with methods.
Here a simple example.

var SizeManager = {
    width : 800,
    height : 600,
    ratio : this.width / this.height,
    resize : function (newWidth) {
        width = newWidth;
        height = newWidth / ratio;
    }
}

My issue is that SizeManager.ratio returns "NaN". I'm quite sure it's an initialization issue.
Is there a way to obtain a correct ratio value?
Is there a way to assign a costructor or initializer to an object literal?
Is defining a constructor objcet the only way?

EDIT: off course SizeManager is ideally a singleton (only one object), that's way i was using object literal.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

╭⌒浅淡时光〆 2024-10-02 02:58:06

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

(我在本文最后从您的具体示例中指出了一些有关比率的内容,但首先让我们针对您提出的一般情况介绍一些选项。)

Daniel 给了你关于使 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 中引用的属性在您的原始版本中缺失,但如果没有它们,您将处理 隐式全局变量的恐怖,这是一件坏事(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;
    }
};

但这只是针对特定示例,因此上面的讨论讨论的是一般情况。

Yes, it's an initialization issue. this does not refer to your SizeManager object at the point you're using it. (Object initializers don't change the value of this.) this is set by how you call a function and has the same value throughout that function call. You're not calling any function there, so this has whatever value it had prior to the beginning of that code.

(I've pointed out something about ratio from your specific example at the very end of this, but first let's walk through a few options for the general case you raise.)

Daniel's given you a good steer on making ratio a function except he doesn't seem to have realized that you want to vary the width. Alternately, if width and height aren't going to change, just calculate it afterward:

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: I've added this. to the properties you're referencing in resize. They were missing from your original, but they're required. Without them, you're dealing with the horror of implicit globals, which is a Bad Thing(tm).)

Of course, you might encapsulate all of that into a factory:

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);

...but then you might as well make it an actual constructor function so you don't create lots of duplicate (but identical) resize functions:

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 I changed the names a bit on this last one.)

And as one last final note: In your specific example, you don't actually need to store ratio at all, you could do this:

var SizeManager = {
    width : 800,
    height : 600,
    resize : function (newWidth) {
        var ratio = this.width / this.height;
        this.width = newWidth;
        this.height = newWidth / ratio;
    }
};

But that's just for that specific example, hence the discussion above to talk about the general case.

不再让梦枯萎 2024-10-02 02:58:06

如果您希望它根据 widthheight 的变化而变化,您的 ratio 属性实际上应该是一个方法:

var SizeManager = {
    width : 800,
    height : 600,
    ratio : function() {
      return this.width / this.height;
    },
    resize : function (newWidth) {
        width = newWidth;
        height = newWidth / ratio;
    }
}

另外,您可能想参考到 this.widththis.height 而不是 resize 中的 widthheight > 方法。

Your ratio property should actually be a method if you want it to change based on changes to width and height:

var SizeManager = {
    width : 800,
    height : 600,
    ratio : function() {
      return this.width / this.height;
    },
    resize : function (newWidth) {
        width = newWidth;
        height = newWidth / ratio;
    }
}

Also, you probably want to refer to this.width and this.height instead of width and height in the resize method.

離殇 2024-10-02 02:58:06

在对象字面量中,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;
  }
}

In an object literal, this only refers to the object literal itself when it is inside a function. You can try something like this instead of an object literal; this will refer to the object you are creating both inside and outside of functions.

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

That will work for a singleton pattern. If you need more than one SizeManager, make it a constructor function instead of an object.

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;
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文