Why can't I use Backbone.Collection as a gener

2019-05-06 17:39发布

问题:

After I asked this question and realized that Backbone.Collections are strictly for Backbone.Models, I'm a little disappointed.

What I was hoping for:

Make underscore's methods more object oriented:

_.invoke(myCollection, 'method');  ==>  myCollection.invoke('method');

I'll admit, minor difference, yet still it seems nice.

What problems will I run into if I use Backbone.Collection for non-Backbone.Models?

Are there any existing implementations, or a simple way to make a generic underscore collection class?

回答1:

While you can't use a Backbone Collection without using models, I came up with a clever way to mix in underscore into the Array prototype:

// This self-executing function pulls all the functions in the _ object and sticks them
// into the Array.prototype
(function () {
    var mapUnderscoreProperty = function (prp) {
        // This is a new function that uses underscore on the current array object
        Array.prototype[prp] = function () {
            // It builds an argument array to call with here
            var argumentsArray = [this];
            for (var i = 0; i < arguments.length; ++i) {
                argumentsArray.push(arguments[i]);
            }

            // Important to note: This strips the ability to rebind the context
            // of the underscore call
            return _[prp].apply(undefined, argumentsArray);
        };
    };

    // Loops over all properties in _, and adds the functions to the Array prototype
    for (var prop in _) {
        if (_.isFunction(_[prop])) {
            mapUnderscoreProperty(prop);
        }
    }
})();

Here is an example of how to use the new Array prototypes:

var test = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

console.log(test.filter(function (item) {
    return item > 2 && item < 7;
})); // Logs [3, 4, 5, 6]
console.log(test); // Logs the entire array unchanged

This solution might add more to the Array prototype than is actually useful, but it gets you the bulk of the functions. Another solution would be to only add functions that have an iterator argument, but this is a start for you.