【问题标题】:How does javascript x = y work when dealing with objects?javascript x = y 在处理对象时如何工作?
【发布时间】:2011-08-29 17:17:36
【问题描述】:

我正在使用 Omniture 标记,并且页面上有许多事件。在omniture中,基础对象是s这个对象是由Omniture全局创建的。

s 对象有许多我喜欢为其设置的“标准”变量,网址、页面标题、网站停留时间、你有什么...

我为每个事件设置一个或两个附加属性

我认为我在编写如下函数方面非常聪明:

 //  s is a global variable create by omniture

 function ClickFoo(){
      var s_ = s;  // make a copy of s which has all the standard vars
      s_.event = "Click Foo";  // set X number of custom vars 
      s_.prop1 = "foo";
      s_.t();    // the Omniture "submit event" function
 }

 function ClickBar(){
      var s_ = s;
      s_.event = "Click Bar";
      s_.prop2 = "bar";
      s_.t();    
 }

 ClickFoo();
 ClickBar();
 // at this point, s.prop1 = "foo"

如果用户单击foo,则bar 将在提交栏上设置s_.prop1 对象属性。

我一直在 JS 控制台中查看这些东西的行为,似乎对 s_ 的更改对全局对象 s 有影响。

谁能解释一下作业是如何进行的,这样我以后就不会犯这个错误了?有没有一种快速正确的方法?

【问题讨论】:

    标签: javascript variable-assignment adobe-analytics


    【解决方案1】:

    你首先拥有的是一个对象和一个引用它的变量:

    然后你要做的是为同一个对象设置另一个变量:

    因此,当更改 _s 时,您正在处理与 s 完全相同的对象,因此您也可以使用 s 获得这些更改后的值。

    相反,您需要两个不同的对象,基本上是克隆:

    有几个可用的克隆 sn-ps。在 jQuery 中,就像 $.extend({}, obj) 一样简单,在原生 JavaScript 中,例如可以使用 this one

    【讨论】:

    • 如果你使用 ExtJS:var cloneS = Ext.extend(S, {});
    【解决方案2】:

    var _s = s; 不是复制s,而是让_ss 引用同一个对象。您将需要创建一个新对象或将原始对象的属性复制到 _s 中。您可以使用clone methods

    Object.prototype.clone = function() {
      var newObj = (this instanceof Array) ? [] : {};
      for (i in this) {
        if (i == 'clone') continue;
        if (this[i] && typeof this[i] == "object") {
          newObj[i] = this[i].clone();
        } else newObj[i] = this[i]
      } return newObj;
    };
    
    ...
    var _s = s.clone(); // _s now does not reference the same object as s
    

    【讨论】:

      【解决方案3】:

      将对象分配给变量时,会复制对变量的引用。该对象不会以任何方式“克隆”。所以:

      var a = {},
          b = a;
      
      b.foo = 'bar';
      alert(a.foo); // 'bar'
      

      这是故意的行为。 (顺便说一句,a == b if ab 是对象的唯一情况是它们是对 same 对象的引用。)

      如果你想故意克隆一个对象,那就有点棘手了。如果你有一个现代浏览器,你可以使用Object.create 有效地克隆一个对象:

      var a = {},
          b = Object.create(a);
      
      b.foo = 'bar';
      alert(a.foo); // undefined
      

      您可以使用该 MDN 页面中的方法将此行为修补到您的应用程序中:

      if (!Object.create) {
          Object.create = function (o) {
              if (arguments.length > 1) {
                  throw new Error('Object.create implementation only accepts the first parameter.');
              }
              function F() {}
              F.prototype = o;
              return new F();
          };
      }
      

      From MDN

      因此,如果您使用此代码,则可以在方法的顶部执行此操作:

      var s_ = Object.create(s);
      

      然后您将处理单独的对象,并且您发现的问题不会发生。

      【讨论】:

        【解决方案4】:

        考虑与对象分离的引用。

        _s 和 s 都是引用。在声明中,

        var _s = s;
        

        您正在将 s 中的引用值复制到 _s。所以它们现在指的是同一个对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-09-17
          • 1970-01-01
          • 2016-01-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多