如何利用值来存储克隆对象?

时间:2013-03-21 13:46:53

标签: javascript jquery

我将css值存储在一个对象中,以便在两种不同的场景中使用:

styles = {
  on: { left:10, top:20 },
  off: { left:0, top:30 }
};

我使用它的第一种方法是简单的鼠标悬停效果:

$nav.hover(
  function() {
    $(this).css(styles.on);
  },
  function() {
    $(this).css(styles.off);
  }
);

但是,对于我的其他用途,我正在制作动画,我需要额外的(非css)属性,如easeonComplete。理想情况下,我希望能够复制styles对象,并将我的新属性添加到它中:

var anim = styles;
anim.ease = Power3.easeInOut;
anim.onComplete = function() {/*stuff*/};

这适用于第二次使用但不幸的是,由于存储了按值引用,这也会将新属性添加到原始styles变量,这反过来将导致{{1}尝试将.css()等分配为css值的方法。

如何快速克隆源对象以添加到新属性中而不影响原始属性?

我知道有关Javascript是否可以通过引用传递的论据(Is there thing like pass by value pass by reference in JavaScript?Is JavaScript a pass-by-reference or pass-by-value language?),但我不想就此进行讨论......

2 个答案:

答案 0 :(得分:1)

在这种情况下,一个简单的对象文字,快速和肮脏的方式将是这样:

var anim = JSON.parse(JSON.stringify(styles));

如果styles对象总是如此简单,那么你应该没问题。当然,如果你要乱用函数(方法)或那里的多级循环引用,你可能需要付出更多努力。

如果styles无法预测,但您希望能够从其克隆中访问它,则可以执行以下操作:

var anim = {on: {}, off: {}};
for (var prop in anim)
{//only loop through anim's properties, as we don't know how many "styles" might have
    if (anim.hasOwnProperty(prop))
    {
        anim[prop].left = styles[prop].left || 'default value';
        anim[prop].top = styles[prop].top || 'default value';
    }
}
anim.original = styles;//reference original object...

理论上,你可以创建一个使用原始对象作为原型的构造函数,但这有点矫枉过正IMHO

答案 1 :(得分:1)

反之亦然(从styles复制到具有自定义属性的新对象)并使用$.extend

$(this).animate($.extend({
   ease: Power3.easeInOut,
   onComplete: function() {/*stuff*/}
}, styles.off));

如果要覆盖其中一些,还可以通过将属性复制到新对象来使用$.extend进行克隆:

$(this).animate($.extend({}, styles.off,
   left: 5,
   ease: Power3.easeInOut,
   onComplete: function() {/*stuff*/}
}));