开发者

How does javascript x = y work when dealing with objects?

开发者 https://www.devze.com 2023-04-01 01:50 出处:网络
I am working with Omniture tagging and I\'ve got numerous events on the page.In omniture, the base object is s this object is created globally by Omniture.

I am working with Omniture tagging and I've got numerous events on the page. In omniture, the base object is s this object is created globally by Omniture.

The s object has a number of "standard" variables that I like to set for it, url, pagetitle, time on site, what have you...

For each event I set one or two additional properties

I thought I was being really clever in writing functions like:

 //  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"

If the user clicks foo then bar the s_.prop1 object property is set on the bar submit.

I've been looking at the behavior of this stuff in the JS console and it seems that changes to s_ have an effect on the global object s.

Can anyone explain how the assignment is working so I don't make this开发者_开发技巧 mistake in future? Is there a quick way to do this correctly?


What you basically have at first is an object and a variable referencing it:

How does javascript x = y work when dealing with objects?

What you're then doing is setting another variable to the same object:

How does javascript x = y work when dealing with objects?

So when altering _s, you're dealing with the exact same object as s and hence you get those altered values with s as well.

Instead, you want two different objects, basically clones:

How does javascript x = y work when dealing with objects?

There are several clone snippets available. In jQuery, it's as easy as $.extend({}, obj), and in vanilla JavaScript this one can be used for example.


var _s = s; is not copying s, but makes both _s and s reference the same object. You will need to either create a new object or copy the properties of the original object into _s. There are clone methods you could use:

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


When you assign an object to a variable, the reference to the variable is copied. The object is not "cloned" in any way. So:

var a = {},
    b = a;

b.foo = 'bar';
alert(a.foo); // 'bar'

This is intentional behaviour. (As a side point, the only time when a == b if a and b are objects is if they are references to the same object.)

If you want to deliberately clone an object, it's a little trickier. If you have a modern browser, you can use Object.create to clone an object effectively:

var a = {},
    b = Object.create(a);

b.foo = 'bar';
alert(a.foo); // undefined

You can patch this behaviour into your application by using the method in that MDN page:

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

So if you use this code, you could then do this at the top of your methods:

var s_ = Object.create(s);

You would then be working on separate objects and the problems you found would not happen.


Think of references being decoupled from objects.

_s and s are both references. In the statement,

var _s = s;

you are copying the referenced value in s to _s. So they now refer to the same object.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号