Cleanup custom Underscore.js

This commit is contained in:
djmaze 2020-07-23 20:50:20 +02:00
parent 134cb7d52a
commit 281a5df732
3 changed files with 64 additions and 108 deletions

View file

@ -14,40 +14,11 @@ _.throttle
// --------------
// Create a safe reference to the Underscore object for use below.
var _ = function(obj) {
if (obj instanceof _) return obj;
if (!(this instanceof _)) return new _(obj);
};
var _ = function() { };
// Export the Underscore object for **Node.js**, with
// backwards-compatibility for their old module API. If we're in
// the browser, add `_` as a global object.
// (`nodeType` is checked to ensure that `module`
// and `exports` are not HTML elements.)
if (typeof exports != 'undefined' && !exports.nodeType) {
if (typeof module != 'undefined' && !module.nodeType && module.exports) {
exports = module.exports = _;
}
exports._ = _;
} else {
// Establish the root object, `window` (`self`) in the browser, `global`
// on the server, or `this` in some virtual machines. We use `self`
// instead of `window` for `WebWorker` support.
var root = typeof self == 'object' && self.self === self && self ||
typeof global == 'object' && global.global === global && global ||
this ||
{};
root._ = _;
}
// Current version.
_.VERSION = '1.9.2';
// An internal function for creating a new object that inherits from another.
var baseCreate = function(prototype) {
if (typeof prototype !== 'object') return {};
return Object.create(prototype);
};
// Establish the root object, `window` (`self`) in the browser.
// We use `self`instead of `window` for `WebWorker` support.
(typeof self == 'object' && self.self === self && self || {})._ = _;
// Function (ahem) Functions
// ------------------
@ -56,21 +27,22 @@ _.throttle
// or a normal function with the provided arguments.
var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) {
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
var self = baseCreate(sourceFunc.prototype);
var result = sourceFunc.apply(self, args);
var fp = sourceFunc.prototype,
self = (typeof fp !== 'object') ? {} : Object.create(fp),
result = sourceFunc.apply(self, args);
return (typeof result === 'object') ? result : self;
};
// Defers a function, scheduling it to run after the current call stack has
// cleared.
_.defer = (() => {
var func = (func, wait, ...args) => setTimeout(() => func.apply(null, args), wait);
var bound = function(...params) {
var position = 0;
var args = [params[position++], 1];
while (position < params.length) args.push(params[position++]);
return executeBound(func, bound, this, this, args);
};
var func = (func, wait, ...args) => setTimeout(() => func.apply(null, args), wait),
bound = function(...params) {
var pos = 1,
args = [params[0], 1];
while (pos < params.length) args.push(params[pos++]);
return executeBound(func, bound, this, this, args);
};
return bound;
})();
@ -80,44 +52,41 @@ _.throttle
// but if you'd like to disable the execution on the leading edge, pass
// `{leading: false}`. To disable execution on the trailing edge, ditto.
_.throttle = function(func, wait, options) {
var timeout, context, args, result;
var previous = 0;
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : Date.now();
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
};
var throttled = function() {
var now = Date.now();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
var timeout, context, args, result,
previous = 0,
later = function() {
previous = options.leading === false ? 0 : Date.now();
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
},
throttle = (...args) => {
var now = Date.now();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
throttled.cancel = function() {
throttle.cancel = () => {
clearTimeout(timeout);
previous = 0;
timeout = context = args = null;
};
return throttled;
return throttle;
};
// Returns a function, that, as long as it continues to be invoked, will not
@ -125,45 +94,31 @@ _.throttle
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
var timeout, result;
var timeout, result,
later = (context, args) => {
timeout = null;
if (args) result = func.apply(context, args);
},
debounce = function(...args) {
if (timeout) clearTimeout(timeout);
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(later, wait);
if (callNow) result = func.apply(this, args);
} else {
var obj = this;
timeout = setTimeout(() => later.apply(null, [obj, args]), wait);
}
var later = function(context, args) {
timeout = null;
if (args) result = func.apply(context, args);
};
return result;
};
var debounced = function(...args) {
if (timeout) clearTimeout(timeout);
if (immediate) {
var callNow = !timeout;
timeout = setTimeout(later, wait);
if (callNow) result = func.apply(this, args);
} else {
var obj = this;
timeout = setTimeout(() => later.apply(null, [obj, args]), wait);
}
return result;
};
debounced.cancel = function() {
debounce.cancel = () => {
clearTimeout(timeout);
timeout = null;
};
return debounced;
return debounce;
};
// AMD registration happens at the end for compatibility with AMD loaders
// that may not enforce next-turn semantics on modules. Even though general
// practice for AMD registration is to be anonymous, underscore registers
// as a named module because, like jQuery, it is a base library that is
// popular enough to be bundled in a third party lib, but not be part of
// an AMD load request. Those cases could generate an error when an
// anonymous define() is called outside of a loader request.
if (typeof define == 'function' && define.amd) {
define('underscore', [], function() {
return _;
});
}
})();