Javascript 中的对象何时被构造?

发布于 2024-07-30 15:09:21 字数 1191 浏览 9 评论 0原文

考虑下面的 Javascript 函数 (1):

function setData(domElement) {
  domElement.myDataProperty = {
    'suppose': 'this',
    'object': 'is',
    'static': 'and',
    'pretty': 'big'
  };
};

现在我不喜欢这个函数的是,每次调用该函数时都会创建完全相同的对象。 由于该对象不会改变,我宁愿只创建它一次。 因此,我们可以进行以下调整(2):

var dataObject = {
  'suppose': 'this',
  'object': 'is',
  'static': 'and',
  'pretty': 'big'
};

function setData(domElement) {
  domElement.myDataProperty = dataObject;
};

现在,该对象在脚本加载时创建一次并存储在 dataObject 中。 但我们假设 setData 仅偶尔被调用 - 大多数情况下,加载脚本时该函数都不会被使用。 在这种情况下,我不喜欢这个函数的是,对象总是被创建并保存在内存中,包括许多永远不会使用它的场合。 我想你可以做这样的事情来达到理想的平衡 (3):

var dataObject;

function setData(domElement) {
  if (!dataObject) {
    dataObject = {
      'suppose': 'this',
      'object': 'is',
      'static': 'and',
      'pretty': 'big'
    };
  }
  domElement.myDataProperty = dataObject;
};

这有意义吗? 我认为这取决于解释器决定创建对象的时间。 它真的会等到通过 !dataObject 条件,还是会进入函数,尝试变得聪明并决定提前构造它? 也许不同的 Javascript 引擎对此有不同的政策?

当然,还有一个问题是这些优化在实践中是否重要。 显然,这取决于对象的大小、引擎的速度、可用资源量等因素。但总的来说,您认为哪一个是更重要的优化:从(1)到(2)或者从(2)到(3)?

Consider the following Javascript function (1):

function setData(domElement) {
  domElement.myDataProperty = {
    'suppose': 'this',
    'object': 'is',
    'static': 'and',
    'pretty': 'big'
  };
};

Now what I don't like about this function is that the exact same object is created every time the function is called. Since the object does not change I would rather create it just once. So we could make the following adjustments (2):

var dataObject = {
  'suppose': 'this',
  'object': 'is',
  'static': 'and',
  'pretty': 'big'
};

function setData(domElement) {
  domElement.myDataProperty = dataObject;
};

Now the object is created once when the script is loaded and stored in dataObject. But let's assume that setData is called only occasionally -- most of the times that the script is loaded the function is not used. What I don't like about this function in that case is that the object is always created and held in memory, including many occasions in which it will never be used. I figured you could do something like this to strike the ideal balance (3):

var dataObject;

function setData(domElement) {
  if (!dataObject) {
    dataObject = {
      'suppose': 'this',
      'object': 'is',
      'static': 'and',
      'pretty': 'big'
    };
  }
  domElement.myDataProperty = dataObject;
};

Would that make sense? I figure it depends on when the interpreter decides to create an object. Does it really wait until it passes the !dataObject condition, or does it enter the function, tries to be smart and decides to construct it in advance? Perhaps different Javascript engines have different policies with regard to this?

Then of course there is the question of whether these optimizations will ever matter in practice. Obviously this depends on factors like the size of the object, the speed of the engine, the amount of resources available, etc.. But in general, which one would you say is the more significant optimization: from (1) to (2) or from (2) to (3)?

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

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

发布评论

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

评论(5

給妳壹絲溫柔 2024-08-06 15:09:21

答案是,你不应该知道。 您展示的示例之间几乎没有什么区别。 您合理担心这一点的唯一方法是,如果您有实际证据表明某种方式明显损害了特定解释器的性能或内存使用情况。 在那之前,口译员的工作就是为您担心这些事情。

也就是说,如果你真的想知道……尝试一下就知道了。 调用不同版本 1,000,000 次,看看有什么不同。

制作一个巨大的物体,看看是否会产生凹痕。 观看任务管理器。 尝试不同的浏览器。 报告您的结果。 与仅仅在互联网上询问一群混蛋他们猜测的情况相比,这是一种更好的查明情况的方法。

请记住,无论如何,对象都必须位于内存中,无论...作为源文本

The answer is, you're not supposed to know. The examples you showed have very little difference between them. The only way you'd ever reasonably worry about this is if you had actual evidence that one way or another was noticably harming performance or memory usage on a particular interpreter. Until then, it's the interpreter's job to worry about that stuff for you.

That said, if you really want to know... Try it and find out. call the different versions 1,000,000 times and see what difference it makes.

Make a giant version of the object and see if that makes a dent. Watch task manager. Try different browsers. Report back your results. It's a much better way to find out than just asking a bunch of jerks on the internet what they guess might be the case.

just keep in mind that object has to be in memory anyway, regardless ... as source text

月下凄凉 2024-08-06 15:09:21

必须创建一个新对象 - 它不能不创建,部分是因为规范要求它,但主要是因为替代行为会违反直觉,采取:

function f() {
    return {a : "b", c: "d"};
}
o=f();
alert([o.c, o.e]); // Alerts "b,"
delete o.c;
o.e="f";
o=f();
alert([o.c, o.e]); // If the object was only created once this would produce ",f"

您真的期望一个新对象表达式实际上不会生成您所要求的对象吗为了? 因为这似乎就是你想要的。

可以想象,您只想这样做:

var myFunction = (function(){
    var object = {a: "b", c: "d"};
    return function() { return object; }
})();

这将获得您想要的效果,尽管您必须意识到您返回的对象是一个可以更改的完全可变的对象,并且每个人都将共享相同的变异实例。

A new object must be created -- it cannot not be, partially because the spec requires it, but mostly because alternative behaviour would be counter intuitive, take:

function f() {
    return {a : "b", c: "d"};
}
o=f();
alert([o.c, o.e]); // Alerts "b,"
delete o.c;
o.e="f";
o=f();
alert([o.c, o.e]); // If the object was only created once this would produce ",f"

Do you really expect a new object expression to not actually produce the object you're asking for? Because that's what you seem to want.

Conceivably you just want to do:

var myFunction = (function(){
    var object = {a: "b", c: "d"};
    return function() { return object; }
})();

Which would get the effect you want, although you would have to realise that the object you're returning is a completely mutable object that can be changed, and everyone would be sharing that same mutating instance.

帝王念 2024-08-06 15:09:21

首先,我会在情况 #2 中实现它,并在页面加载后立即加载一次。

如果页面速度存在问题,我会测量页面内特定任务所花费的时间。

如果创建对象非常昂贵(相对而言),那么我会转向情况 #3。

如果添加“if”语句确实没有给您带来任何好处,那么添加“if”语句就没有意义……在这种情况下,创建一个简单/大的对象对您的 CPU 来说并不费力。 没有测量,你就没有优化——你只是盲目地拍摄。

这实际上是我个人在 C++ 和 Java 中使用过的一种相当常见的初始化方法。

First, I'd implement it in situation #2 and load it once immediately after the page is loaded.

If there was a problem with page speed, I would measure the time taken for specific tasks within the page.

If it was very expensive to create the object (relatively speaking), then I would move to situation #3.

There's no point in adding the 'if' statement if it really doesn't buy you anything... and in this case, creating a simple/big object is no sweat off your CPU's back. Without measurements, you're not optimizing - you're just shooting blind.

It's actually a fairly common method of initializing things that I've personally used in C++ and Java.

娇俏 2024-08-06 15:09:21

首先,这种优化在实践中永远不会重要。

其次,最后一个函数与第一个函数完全一样好。 嗯,差不多了。 在第一个例子中,我认为您受到垃圾收集器的支配,当您重新分配 domElement.myDataProperty 时,垃圾收集器应该会销毁旧对象。 不过,如果不确切知道垃圾收集器在目标平台上的工作原理(并且不同浏览器的情况可能会有很大不同),您就无法确定是否真的节省了任何工作。

First, this optimization will never matter in practice.

Second, the last function is exactly as good as the first function. Well, almost. In the first I suppose you're at the mercy of the garbage collector, which should destroy the old object when you reassign domElement.myDataProperty. Still, without knowing exactly how the garbage collector works on your target platform (and it can be very different across browsers), you can't be sure you're saving any work at all really.

兔姬 2024-08-06 15:09:21

在几个浏览器中尝试所有这三个方法,看看哪个更快。

Try all three of them in a couple of browsers and find out which is faster.

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