1

私は Omniture のタグ付けに取り組んでおり、ページには多数のイベントがあります。omn​​iture では、基本オブジェクトはs、このオブジェクトが Omniture によってグローバルに作成されます。

オブジェクトにはs、URL、ページタイトル、サイト滞在時間など、設定したい「標準」変数がいくつかあります...

イベントごとに、1 つまたは 2 つの追加プロパティを設定します

次のような関数を書くのは本当に賢いと思いました。

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

ユーザーがクリックするfoobars_.prop1オブジェクト プロパティがバーの送信に設定されます。

私は JS コンソールでこのような動作を見てきましたが、s_ への変更がグローバル オブジェクト s に影響を与えているようです。

今後この間違いをしないように、誰かが割り当てがどのように機能しているかを説明できますか? これを正しく行う簡単な方法はありますか?

4

4 に答える 4

7

基本的に最初に持っているのは、オブジェクトとそれを参照する変数です。

ここに画像の説明を入力

次に、別の変数を同じオブジェクトに設定しています。

ここに画像の説明を入力

したがって、 を変更_sすると、 とまったく同じオブジェクトを扱っているsため、これらの変更された値も取得sします。

代わりに、基本的にクローンである 2 つの異なるオブジェクトが必要です。

ここに画像の説明を入力

利用可能ないくつかのクローン スニペットがあります。jQuery では と同じくらい簡単で、たとえば$.extend({}, obj)バニラ JavaScript ではこれを使用できます。

于 2011-08-29T17:28:16.220 に答える
5

var _s = s;はコピーしていませんsが、両方_ss作成し、同じオブジェクトを参照しています。新しいオブジェクトを作成するか、元のオブジェクトのプロパティを _s にコピーする必要があります。使用できる複製方法があります。

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
于 2011-08-29T17:24:18.427 に答える
3

オブジェクトを変数に割り当てると、変数への参照がコピーされます。オブジェクトは決して「複製」されません。そう:

var a = {},
    b = a;

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

これは意図的な動作です。(余談ですが、a == bifabがオブジェクトであるのは、それらが同じオブジェクトへの参照である場合のみです。)

意図的にオブジェクトのクローンを作成したい場合は、少しトリッキーです。最新のブラウザーを使用している場合は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();
    };
}

MDN から

したがって、このコードを使用する場合、メソッドの先頭でこれを行うことができます。

var s_ = Object.create(s);

その後、別のオブジェクトで作業することになり、発見した問題は発生しません。

于 2011-08-29T17:27:57.937 に答える
1

参照がオブジェクトから分離されていると考えてください。

_s と s は両方とも参照です。声明では、

var _s = s;

s の参照値を _s にコピーしています。したがって、これらは同じオブジェクトを参照するようになりました。

于 2011-08-29T17:28:19.943 に答える