Avoid binding functions in _.createCallback if they don't reference this.

Former-commit-id: d491414e7e1536d3241a607ba07120f629ff2410
This commit is contained in:
John-David Dalton
2013-05-20 09:20:51 -07:00
parent 242e8a3bd6
commit 01621f75b6
3 changed files with 116 additions and 35 deletions

View File

@@ -1385,6 +1385,9 @@
function removeRunInContext(source) { function removeRunInContext(source) {
source = removeVar(source, 'contextProps'); source = removeVar(source, 'contextProps');
// replace reference in `reThis` assignment
source = source.replace(/\btest\(runInContext\)/, 'test(function() { return this; })');
// remove function scaffolding, leaving most of its content // remove function scaffolding, leaving most of its content
source = source.replace(matchFunction(source, 'runInContext'), function(match) { source = source.replace(matchFunction(source, 'runInContext'), function(match) {
return match return match

View File

@@ -55,6 +55,9 @@
/** Used to match "interpolate" template delimiters */ /** Used to match "interpolate" template delimiters */
var reInterpolate = /<%=([\s\S]+?)%>/g; var reInterpolate = /<%=([\s\S]+?)%>/g;
/** Used to detect functions containing a `this` reference */
var reThis = (reThis = /\bthis\b/) && reThis.test(runInContext) && reThis;
/** Used to detect and test whitespace */ /** Used to detect and test whitespace */
var whitespace = ( var whitespace = (
// whitespace // whitespace
@@ -188,6 +191,7 @@
clearTimeout = context.clearTimeout, clearTimeout = context.clearTimeout,
concat = arrayProto.concat, concat = arrayProto.concat,
floor = Math.floor, floor = Math.floor,
fnToString = Function.prototype.toString,
getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
hasOwnProperty = objectProto.hasOwnProperty, hasOwnProperty = objectProto.hasOwnProperty,
push = arrayProto.push, push = arrayProto.push,
@@ -4578,27 +4582,27 @@
return result; return result;
}; };
} }
if (typeof thisArg != 'undefined') { if (typeof thisArg == 'undefined' || (reThis && !reThis.test(fnToString.call(func)))) {
if (argCount === 1) { return func;
return function(value) { }
return func.call(thisArg, value); if (argCount === 1) {
}; return function(value) {
} return func.call(thisArg, value);
if (argCount === 2) {
return function(a, b) {
return func.call(thisArg, a, b);
};
}
if (argCount === 4) {
return function(accumulator, value, index, collection) {
return func.call(thisArg, accumulator, value, index, collection);
};
}
return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
}; };
} }
return func; if (argCount === 2) {
return function(a, b) {
return func.call(thisArg, a, b);
};
}
if (argCount === 4) {
return function(accumulator, value, index, collection) {
return func.call(thisArg, accumulator, value, index, collection);
};
}
return function(value, index, collection) {
return func.call(thisArg, value, index, collection);
};
} }
/** /**

View File

@@ -1129,6 +1129,80 @@
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
QUnit.module('exclude command');
(function() {
var commands = [
'exclude',
'minus'
];
commands.forEach(function(command) {
asyncTest('`lodash ' + command + '=runInContext`', function() {
var start = _.after(2, _.once(QUnit.start));
build(['-s', command + '=runInContext'], function(data) {
var basename = path.basename(data.outputPath, '.js'),
context = createContext(),
source = data.source;
vm.runInContext(data.source, context);
var lodash = context._,
array = [0];
var actual = lodash.map(array, function() {
return String(this[0]);
}, array);
deepEqual(actual, ['0'], basename);
equal('runInContext' in lodash, false, basename);
start();
});
});
asyncTest('`lodash ' + command + '=mixin`', function() {
var start = _.after(2, _.once(QUnit.start));
build(['-s', command + '=mixin'], function(data) {
var basename = path.basename(data.outputPath, '.js'),
context = createContext(),
source = data.source;
vm.runInContext(data.source, context);
var lodash = context._;
var actual = lodash([1, 2, 3])
.map(function(num) { return num * num; })
.value();
deepEqual(actual, [1, 4, 9], basename);
equal('mixin' in lodash, false, basename);
start();
});
});
asyncTest('`lodash ' + command + '=value`', function() {
var start = _.after(2, _.once(QUnit.start));
build(['-s', command + '=value'], function(data) {
var basename = path.basename(data.outputPath, '.js'),
context = createContext(),
source = data.source;
vm.runInContext(data.source, context);
var lodash = context._;
strictEqual(lodash([1]), undefined, basename);
deepEqual(_.keys(lodash.prototype), [], basename);
start();
});
});
});
}());
/*--------------------------------------------------------------------------*/
QUnit.module('exports command'); QUnit.module('exports command');
(function() { (function() {
@@ -1440,19 +1514,19 @@
var command = origCommand; var command = origCommand;
if (index == 1) { if (index == 1) {
if (/legacy|mobile/.test(command)) { if (/\b(?:legacy|mobile)\b/.test(command)) {
return; return;
} }
command = 'mobile ' + command; command = 'mobile ' + command;
} }
else if (index == 2) { else if (index == 2) {
if (/legacy|modern/.test(command)) { if (/\b(?:legacy|modern)\b/.test(command)) {
return; return;
} }
command = 'modern ' + command; command = 'modern ' + command;
} }
else if (index == 3) { else if (index == 3) {
if (/category|legacy|underscore/.test(command)) { if (/\b(?:category|legacy|underscore)\b/.test(command)) {
return; return;
} }
command = 'underscore ' + command; command = 'underscore ' + command;
@@ -1464,8 +1538,8 @@
var methodNames, var methodNames,
basename = path.basename(data.outputPath, '.js'), basename = path.basename(data.outputPath, '.js'),
context = createContext(), context = createContext(),
isBackbone = /backbone/.test(command), isBackbone = /\bbackbone\b/.test(command),
isUnderscore = isBackbone || /underscore/.test(command), isUnderscore = isBackbone || /\bunderscore\b/.test(command),
exposeAssign = !isUnderscore, exposeAssign = !isUnderscore,
exposeZipObject = !isUnderscore; exposeZipObject = !isUnderscore;
@@ -1475,11 +1549,11 @@
console.log(e); console.log(e);
} }
// add method names explicitly // add method names explicitly
if (/include/.test(command)) { if (/\binclude=/.test(command)) {
methodNames = command.match(/include=(\S*)/)[1].split(/, */); methodNames = command.match(/\binclude=(\S*)/)[1].split(/, */);
} }
// add method names required by Backbone and Underscore builds // add method names required by Backbone and Underscore builds
if (/backbone/.test(command) && !methodNames) { if (/\bbackbone\b/.test(command) && !methodNames) {
methodNames = backboneDependencies.slice(); methodNames = backboneDependencies.slice();
} }
if (isUnderscore) { if (isUnderscore) {
@@ -1490,20 +1564,20 @@
methodNames = underscoreMethods.slice(); methodNames = underscoreMethods.slice();
} }
} }
if (/category/.test(command)) { if (/\bcategory=/.test(command)) {
methodNames = (methodNames || []).concat(command.match(/category=(\S*)/)[1].split(/, */).map(capitalize)); methodNames = (methodNames || []).concat(command.match(/\bcategory=(\S*)/)[1].split(/, */).map(capitalize));
} }
if (!methodNames) { if (!methodNames) {
methodNames = lodashMethods.slice(); methodNames = lodashMethods.slice();
} }
if (/plus/.test(command)) { if (/\bplus=/.test(command)) {
methodNames = methodNames.concat(command.match(/plus=(\S*)/)[1].split(/, */)); methodNames = methodNames.concat(command.match(/\bplus=(\S*)/)[1].split(/, */));
} }
if (/minus/.test(command)) { if (/\bminus=/.test(command)) {
methodNames = _.without.apply(_, [methodNames].concat(expandMethodNames(command.match(/minus=(\S*)/)[1].split(/, */)))); methodNames = _.without.apply(_, [methodNames].concat(expandMethodNames(command.match(/\bminus=(\S*)/)[1].split(/, */))));
} }
if (/exclude/.test(command)) { if (/\bexclude=/.test(command)) {
methodNames = _.without.apply(_, [methodNames].concat(expandMethodNames(command.match(/exclude=(\S*)/)[1].split(/, */)))); methodNames = _.without.apply(_, [methodNames].concat(expandMethodNames(command.match(/\bexclude=(\S*)/)[1].split(/, */))));
} }
// expand categories to real method names // expand categories to real method names