I'm going through Immutable.js's source code and there's an ownerID field that I don't understand.
Here's the source for Map.asMutable() and Map.asImmutable(): https://github.com/facebook/immutable-js/blob/master/src/Map.js#L171
It seems like the only difference between a mutable and an immutable object are their ownerIDs. What is an ownerID and what is it used for?
3 Answers
Answers 1
If you track back the property:
L#14:
import { DELETE, SHIFT, SIZE, MASK, NOT_SET, CHANGE_LENGTH, DID_ALTER, OwnerID, MakeRef, SetRef, arrCopy } from './TrieUtils' in src/TrieUtils.js :
L#36:
// A function which returns a value representing an "owner" for transient writes // to tries. The return value will only ever equal itself, and will not equal // the return of any subsequent call of this function. export function OwnerID() {} It is some property they create like hash to represent a virtual owner.
Answers 2
It is used to ensure mutability in asMutable returned instances. When asMutable is invoked, it ensures an __ownerId and returns the current instance back -
asMutable() { return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); } Then any supported mutating operations return the current instance back, instead of creating a new instance with the changes (which is key for immutability).
E.g., here's how the "clear" method operates based on the presence of __ownerId -
clear() { if (this.size === 0) { return this; } if (this.__ownerID) { this.size = 0; this._root = null; this.__hash = undefined; this.__altered = true; return this; } return emptyMap(); } Notice that when this.__ownerID is present, the method returns the current instance (thereby mutating itself). But when it is absent, it returns a new map for ensuring immutability.
Answers 3
From the source code:
// A function which returns a value representing an "owner" for transient writes // to tries. The return value will only ever equal itself, and will not equal // the return of any subsequent call of this function. function OwnerID() {} My understanding of the above is that the this.__ownerID field is used to compare objects. A Map being compared against itself will have the same ownerID, while a Map being compared against another Map will see two different ownerIDs.
You can see an example of this usage a little farther down in the file in question:
__ensureOwner(ownerID) { if (ownerID === this.__ownerID) { return this; } if (!ownerID) { this.__ownerID = ownerID; this.__altered = false; return this; } return makeMap(this.size, this._root, ownerID, this.__hash); } In fact, searching the entire repo, you'll see that this function is common across data types, with each type having a slightly modified version to return a correct new version of that type.
0 comments:
Post a Comment