Skip to content

Commit

Permalink
make _.initWrapper() that builds the wrapper prototye
Browse files Browse the repository at this point in the history
The intention is that underscore Consumers MUST call _.initWrapper()
in their code to allow the OO style usage, or a runtime error is thrown.
This would break backwards compatability, so for the moment I call
initWrapper myself at the end of underscore.

However, if I comment out my call to initWrapper and don't call it
in user code, then the compiler can strip an empty underscore with
no user code from 2137 -> 100 bytes.  Making the user explicitly say
they want OO wrapping is the only way to achieve this, otherwise the
compiler will always keep the OO wrapper code around.
  • Loading branch information
ratbeard committed Feb 24, 2010
1 parent 1cf73c5 commit f591f68
Showing 1 changed file with 56 additions and 46 deletions.
102 changes: 56 additions & 46 deletions underscore.js
Expand Up @@ -43,7 +43,7 @@
native_keys = Object['keys'];

// Create a safe reference to the Underscore object for reference below.
var _ = function(obj) { return new wrapper(obj); };
var _ = function(obj) { return _.buildWrapper(obj) };

// Export the Underscore object for CommonJS.
if (typeof exports !== 'undefined') exports._ = _;
Expand All @@ -68,8 +68,11 @@
} else if (_.isNumber(obj.length)) {
for (var i=0, l=obj.length; i<l; i++) iterator.call(context, obj[i], i, obj);
} else {
var keys = _.keys(obj), l = keys.length;
for (var i=0; i<l; i++) iterator.call(context, obj[keys[i]], keys[i], obj);
for (var key in obj)
if (hasOwnProperty.call(obj, key))
iterator.call(context, obj[key], key, obj);
// var keys = _.keys(obj), l = keys.length;
// for (var i=0; i<l; i++) iterator.call(context, obj[keys[i]], keys[i], obj);
}
} catch(e) {
if (e != breaker) throw e;
Expand Down Expand Up @@ -639,53 +642,60 @@
_.methods = _.functions;

// ------------------------ Setup the OOP Wrapper: --------------------------

// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
var wrapper = function(obj) { this._wrapped = obj; };
_.buildWrapper = function () { throw "Call _.initWrapper() to enable OO wrapping" }

// Helper function to continue chaining intermediate results.
var result = function(obj, chain) {
return chain ? _(obj).chain() : obj;
};

// Add all of the Underscore functions to the wrapper object.
each(_.functions(_), function(name) {
var method = _[name];
wrapper.prototype[name] = function() {
var args = _.toArray(arguments);
unshift.call(args, this._wrapped);
return result(method.apply(_, args), this._chain);
};
});

// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = Array_Prototype[name];
wrapper.prototype[name] = function() {
method.apply(this._wrapped, arguments);
return result(this._wrapped, this._chain);
_.initWrapper = function () {
// If Underscore is called as a function, it returns a wrapped object that
// can be used OO-style. This wrapper holds altered versions of all the
// underscore functions. Wrapped objects may be chained.
var wrapper = function(obj) { this._wrapped = obj; };

// Overwrite method called from _()
_.buildWrapper = function (obj) { return new wrapper(obj) };

// Helper function to continue chaining intermediate results.
var result = function(obj, chain) {
return chain ? _(obj).chain() : obj;
};
});

// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
var method = Array_Prototype[name];
wrapper.prototype[name] = function() {
return result(method.apply(this._wrapped, arguments), this._chain);
};
});
// Add all of the Underscore functions to the wrapper object.
each(_.functions(_), function(name) {
var method = _[name];
wrapper.prototype[name] = function() {
var args = _.toArray(arguments);
unshift.call(args, this._wrapped);
return result(method.apply(_, args), this._chain);
};
});

// Start chaining a wrapped Underscore object.
wrapper.prototype.chain = function() {
this._chain = true;
return this;
};
// Add all mutator Array functions to the wrapper.
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
var method = Array_Prototype[name];
wrapper.prototype[name] = function() {
method.apply(this._wrapped, arguments);
return result(this._wrapped, this._chain);
};
});

// Extracts the result from a wrapped and chained object.
wrapper.prototype.value = function() {
return this._wrapped;
};
// Add all accessor Array functions to the wrapper.
each(['concat', 'join', 'slice'], function(name) {
var method = Array_Prototype[name];
wrapper.prototype[name] = function() {
return result(method.apply(this._wrapped, arguments), this._chain);
};
});

// Start chaining a wrapped Underscore object.
wrapper.prototype.chain = function() {
this._chain = true;
return this;
};

// Extracts the result from a wrapped and chained object.
wrapper.prototype.value = function() {
return this._wrapped;
};
}

_.initWrapper();
})();

0 comments on commit f591f68

Please sign in to comment.