Backbone 1.3.3 collection confusion demo

A collection's internal state keeps a reference to a removed model when `remove()`-ing that model as a response to `unset()`-ing its `id` attribute.

by David Bouman

HTML

<script src="https://rawgit.com/jashkenas/underscore/1.8.3/underscore-min.js"></script>
<script src="https://rawgit.com/jashkenas/backbone/1.3.3/backbone-min.js"></script>
<p>
    <em>This fiddle is run against <a href="https://rawgit.com/jashkenas/backbone/1.3.3/backbone-min.js">Backbone 1.3.3</a>.</em>
</p>
<p>
    Demonstrated below is the mixed-up internal state of the <code>collection</code> after the invocation of <code>model.unset('id')</code>:
</p>
<dl>
    <dt><code>collection.models</code>:</dt>
    <dd>
        <textarea id="models"></textarea>
    </dd>

    <dt><code>collection._byId</code>:</dt>
    <dd>
        <textarea id="_byId"></textarea>
    </dd>

    <dt><code>collection.get( 'foo' )</code>:</dt>
    <dd>
        <textarea id="get-foo"></textarea>
    </dd>
</dl>

CSS

code {
    background: #eee;
    border: solid 1px #ddd;
    padding: .2em .3em;
    margin: .1em 0 .2em;
    display: inline-block;
    vertical-align: middle;
}

textarea {
    font-family: monospace;
}

JavaScript

var
    MyView = Backbone.View.extend( {

        initialize: function () {

            this.model = new Backbone.Model( {

                id:  'foo'
            ,   foo: 'bar'
            } );

            this.collection = new Backbone.Collection( this.model );

            this.listenTo( this.model, 'change:id', function ( model, id ) {

                if ( id == null ) {
                    this.collection.remove( model );
                }

            } );

            this.model.unset( 'id' );

            $( '#models'  ).val( JSON.stringify( this.collection.models      ));
            $( '#_byId'   ).val( JSON.stringify( this.collection._byId       ));
            $( '#get-foo' ).val( JSON.stringify( this.collection.get( 'foo' )));
        }

    } )

, foo = new MyView()
;