在JavaScript中,多重赋值var a = b = b || {}的含义是什么?

7

阅读leaflet.js的代码时,我遇到了一种方法,其中有这样一行代码,我并不完全理解:

var events = this._leaflet_events = this._leaflet_events || {};

可以简化为

var a = b = b || {};

据我所了解,这个指令是一个多重左侧赋值,是从右向左进行结合的。这意味着首先JavaScript会运行。
b = b || {} //if b exists, returns b, else return an empty object

然后

a = b // returns the output of the preceding instruction

这对我来说没有意义。为什么不改写成以下形式:
a = b || {};

完整的上下文:

addEventListener: function( /*string*/ type, /*function */ fn, /*(optional) object*/ context){
    var events = this._leaflet_events = this._leaflet_events || {};
        events[type] = events[type] || {};
        events[type].push({
        action: fn,
        context: context || this
        });
    return this;
}

我怀疑这是一个引用技巧,因为我不知道除了该方法之外如何修改this._leaflet_events
仔细想想,编写var a = b = b || {}实际上是一种技巧,可以将var a分配给b的引用,无论是否定义了b。现在修改a会修改b
回到Leaflet。
    var events = this._leaflet_events = this._leaflet_events || {};

this._leaflet_events 要么存在,要么被初始化为 {}events 通过引用分配给了 this._leaflet_events。该引用的值可能是 {},但修改 events 时仍然修改的是 this._leaflet_events

相反地,如果写成:

    var events = this._leaflet_events || {};

如果不定义this._leaflet_events,那么将是一个错误,因为events现在将指向一个新创建的对象,其值为{}。修改events会改变新对象,但不会改变this._leaflet_events的值。

相同的表面值,不同的引用。这就是事情的本质。


请注意,this._leaflet_eventsthis._leaflet.events 是不同的。 - Derek 朕會功夫
2个回答

10

这个语句 var a = b = b || {}; 做了两件事:

  • 如果b未定义,将其初始化为{}
  • 将a设置为与b相同。

表达式a = b || {};不会修改b,因此它不等价。


你没有发现这两个变量名字的不同 - 请看我的答案。 - ThiefMaster
2
@ThiefMaster:我认为这只是问题中的一个打字错误。请检查原始源代码:https://github.com/cvisto/Leaflet/blob/has_clearEventListeners/src/core/Events.js#L23 - Mark Byers

7
较短的表达式不会将任何值设置为b的值。
a = b = b || {}; //set b's b value to {} if b is uncdefined, then set a's value to b

a = b || {}; //set a's value to b, or {} if b is undefined

第一条语句实际上等同于

b = b || {};
a = b;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接