Care to elaborate?
Care to elaborate?
A string key for the underlying map is generated based on the data type of the element being added in the set. If you're adding an object into the set, the object is mutated so that it stores a unique ID. The object's unique ID is used to form the string key that will identify this object in the set.
Note how goog.structs.Set.getKey_ is used in the add() method: https://github.com/google/closure-library/blob/v20160125/clo...
This is how the library obtains the unique ID of an object: https://github.com/google/closure-library/blob/v20160125/clo...
Also, if this was being done for ES5+ code, then either setting that property to non-enumerable or using something like Symbols would be cool since it would hopefully have a reduced impact on other code.
Both libraries provide their own implementation of a Set though, so in practice you would just use the library provided one.
The code they use has the same limitation. It adds / removes / ensures the uniqueness of elements in the set by using Array.indexOf(...), which only works for strings and things that can be uniquely coerced into strings.
So, given this limitation, using an Object-based set would be vastly more performant.
var set = []
var foo = {foot: 1}
var bar = {bart: 2}
set.push(foo)
set.indexOf(foo) //0
set.indexOf(bar) //-1
"indexOf() compares searchElement to elements of the Array using strict equality (the same method used by the ===, or triple-equals, operator)."[0]MDN has the link to the ES5 specification, but the key part is 9(c)(ii):
"Let same be the result of applying the Strict Equality Comparison Algorithm to searchElement and elementK."
[0] - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
var elem = {foo:"bar"}
var set = [elem]
set.indexOf(elem) // 0
set.indexOf({foo:"bar"}) // -1
So I guess the strict equality comparison is using some kind of internal objectId rather than the property name and values of the objects? I guess depend on how you want to define "uniqueness" for your set...So
var x = {foo:"bar"}
var y = {foo:"bar"}
var z = x
x === y //false
x === z //true
This is specified in the ES3 document[0] at 11.9.6(13):"13. Return true if x and y refer to the same object or if they refer to objects joined to each other (see 13.1.2). Otherwise, return false."
[0] - http://www.ecma-international.org/publications/files/ECMA-ST...