Understanding Double Assignment and Operator Precedence in jQuery Code
This article explains why jQuery’s source uses a double assignment pattern, how assignment operators are right‑associative expressions, the impact of operator precedence on property access versus assignment, and demonstrates practical uses such as building linked structures in JavaScript.
Hello, I’m ConardLi. While exploring the fact that the world’s largest e‑commerce site Amazon still uses jQuery, I dug into jQuery’s source code and found an intriguing double‑assignment pattern.
Assignment Operations Are Also Expressions
Assigning a value to a variable is an expression whose result is the right‑hand side (RHS) value. For example:
let x
if (x = 1) { // 1 is truthy
console.log(1) // 1
}The assignment operator = is right‑associative, so chained assignments work as expected:
let a, b
a = b = 2 // the same as a = (b = 2)
console.log(a) // 2
console.log(b) // 2Operator Precedence
The jQuery snippet below contains two assignment operators and a property‑access operator:
elemData.events = elemData = function(){};According to the JavaScript operator‑precedence table, property access (precedence 18) outranks assignment (precedence 2). Therefore the expression is evaluated as:
Evaluate elemData.events (property access).
Evaluate the RHS elemData = function(){} , which first assigns the function to elemData and yields that function.
Assign the yielded function to the previously accessed elemData.events .
Code Walk‑through
var elemData = initialValue // 1
// ...
elemData.events = elemData = function(){}; // 2
// ...
elemData.events = {}; // 3Line 1 simply initializes elemData with initialValue .
Line 2: the old elemData (pointing to initialValue ) is overwritten by the function; simultaneously elemData.events receives that function as its value.
Line 3: elemData.events is later replaced with an empty object, discarding the function reference.
This behavior is similar to what happens in a for…in loop when the iterated object is reassigned mid‑loop; the enumeration continues with the original property list until the loop ends.
let obj = {a:1, b:2, c:3}
let obj2 = {d:1, e:2, f:3}
for (const prop in obj) {
console.log(prop) // a, b, c
obj = obj2
}
console.log(obj) // {d:1, e:2, f:3}Practical Application
The same double‑assignment trick can be used to build data structures such as a linked list:
let i = 0, root = {index: i}, node = root
while (i < 10) {
node.next = node = {} // `node` in `node.next` is the old node
node.index = ++i // `node` in `node.index` is the new node
}
node = root
do {
console.log(node.index) // 0,1,2,...,10
} while ((node = node.next))The diagram below visualises the same concept.
References
https://www.zhenghao.io/posts/double-assignment
Operator precedence table: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#table
Sohu Tech Products
A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.