0

我将 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变量中,这反过来会导致.css()方法尝试将ease等分配为 css 值。

如何在不影响原始属性的情况下快速克隆源对象以添加新属性?

我知道围绕 Javascript 是否可以通过引用传递的论点(在 JavaScript 中是否存在按值传递之类的传递?JavaScript 是按引用传递还是按值传递语言?)但我不知道想就此展开讨论……

4

2 回答 2

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...

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

于 2013-03-21T13:49:37.757 回答
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*/}
}));
于 2013-03-21T14:07:31.310 回答