Source: polyfill/WeakSet.js

// Licensed Materials - Property of IBM
//
// IBM Watson Analytics
//
// (C) Copyright IBM Corp. 2015
//
// US Government Users Restricted Rights - Use, duplication or
// disclosure restricted by GSA ADP Schedule Contract with IBM Corp.

module.exports = ( function( ObjectPolyfill, Symbol )
{
"use strict";

// The property set by the first WeakSet that takes an object as key.
// All WeakSets look at the same property
var KEY_PROP = Symbol( "WeakSet" );
var hOP = Object.prototype.hasOwnProperty;
var nextId = 0;

/**
 * Mimics the implementation of a native {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet WeakSet}.
 * The only way to achieve this is by putting a property on the added value.
 * @class module:barejs/polyfill.WeakSet
 * @param {*} [_iterable]: Optional: an iterable whose values will be added to the WeakSet.
 */
function WeakSet( _iterable )
{
    if ( _iterable )
    {
        for ( var i = 0; i < _iterable.length; ++i )
            this.add( _iterable[i] );
    }

    ObjectPolyfill.defineProperty( this, "_values", { value: [] } );
}

return ( ObjectPolyfill.defineProperties( WeakSet.prototype,
/** @lends module:barejs/polyfill.WeakSet# */
{
    _values: { value: null },

    /**
     * Adds a value to a WeakSet.
     * @function
     * @param _value The value to add.
     * @returns {module:barejs/polyfill.WeakSet} The WeakSet (for chaining)
     */
    add: { value: function add( _value )
    {
        if ( !ObjectPolyfill.isObject( _value ) )
            throw new TypeError( "Invalid value used as WeakSet value" );

        if ( !hOP.call( _value, KEY_PROP ) )
            ObjectPolyfill.defineProperty( _value, KEY_PROP, { value: ++nextId } );

        if ( this._values.indexOf( _value[KEY_PROP] ) < 0 )
            this._values.push( _value[KEY_PROP] );

        return this;
    } },

    /**
     * Check if the WeakSet has an entry for the specified _value.
     * @function
     * @param {object} _value The object to check.
     * @returns {boolean} True if the WeakSet contains _value, false otherwise.
     */
    has: { value: function has( _value )
    {
        // If there is no WeakSet key property on the object, it has never been used as key for a WeakSet
        return ObjectPolyfill.isObject( _value ) && hOP.call( _value, KEY_PROP ) && ( this._values.indexOf( _value[KEY_PROP] ) >= 0 );
    } },

    /**
     * Remove the value from the WeakSet
     * @function
     * @param {object} _value The value to remove.
     * @returns {boolean} True if the value was deleted, false otherwise
     */
    "delete": { value: function _delete( _value )
    {
        var idx = -1;

        if ( ObjectPolyfill.isObject( _value ) && hOP.call( _value, KEY_PROP ) )
            idx = this._values.indexOf( _value[KEY_PROP] );

        if ( idx < 0 )
            return false;

        this._values.splice( idx, 1 );

        return true;
    } }
} ), WeakSet );

}( require( "./Object" ), require( "../Symbol" ) ) );