1

我正在查看 Backbones v1.0.0 源代码并注意到一些有趣的东西。在 Backbone.Events 对象中,“ on ”方法似乎将变量链接到对象值:

 on: function(name, callback, context) {
     if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
     this._events || (this._events = {});
     var events = this._events[name] || (this._events[name] = []);
     events.push({callback: callback, context: context, ctx: context || this});
     return this;
},

events ”变量设置为“ this._events[name] ”值,该值可以是现有数组或设置为空数组。奇怪的部分是将一个对象推入这个数组的下一行。推送之后,如果您现在检查“ this._events[name] ”的值,它现在在其数组的末尾有那个新对象。在我看来,这两者本质上是联系在一起的;当您更新一个时,另一个也会更新。

我以前没有遇到过这样的事情,做一个简单的浏览器控制台测试可以确认这种行为。你更新一个,另一个也得到更新。它似乎只适用于数组的对象值。谁能解释这里发生了什么?我有点困惑?

4

3 回答 3

3

在该var events = this._events[name] || (this._events[name] = []);行之后,events变量和this._events[name]指向同一个数组。因为它们都指向同一个数组,所以不管你是events.push(...)还是this._events[name].push(...),它都会将一个元素推送到两个东西都指向的一个数组上。

这与此完全相同:

var a = [];            // Create an empty array, reference it from `a`
var b = a;             // Now, `b` and `a` both point to the same array
a.push("foo");         // Put an entry in the array
console.log(a.length); // "1", unsurprisingly
console.log(b.length); // "1", because both `a` and `b` point to the same array
于 2013-03-29T17:22:14.213 回答
1

你更新一个,另一个也得到更新。

您只有一个数组,并且正在更新。

Think of variables as "pointers", when they have an object as a value (yes an array counts as an object). The variable is not the object, it simply holds a reference to that object.

This can be demonstrated more simply by this snippet:

var a = [];
var b = a;
a.push('Hello!');
alert(b[0]); // Hello!

You only have one array here, and both the a and b variables point to that same array. You modify that array, and those modifications can be fetched from any variable that points to that array.

于 2013-03-29T17:24:33.310 回答
0

实际上正在发生的事情是一种将事件初始化为数组的简单方法(如果它尚不存在)。事件是一个指向它的指针,this._events[name]它本身是一个指向数组的指针。如果该数组不存在,则将其初始化为一个新数组。

试试这个:

var x = false || 2;
console.log(x);
x = 1 || 2;
console.log(x);
于 2013-03-29T17:23:22.040 回答