This document provides a comprehensive guide on creating valid substitutions for Lodash functions, using the _.isBoolean function as an exemplar.
Retrieving the Original Lodash Functionality
Lodash can be complex, with each function residing in its own file. To simplify the process of determining the original functionality, you can utilize per-method packages provided by Lodash. Follow these steps:
Visit the npm page of the function you want to substitute. In our example, we visit the npm page of the lodash.isboolean package.
Click on the code tab to access the source code of the package, which is bundled in a single file named index.js.
Here is the content of the index.js for reference:
/**
* lodash 3.0.3 (Custom Build) <https://lodash.com/>
* Build: `lodash modularize exports="npm" -o ./`
* Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
* Available under MIT license <https://lodash.com/license>
*/
/** `Object#toString` result references. */
var boolTag = '[object Boolean]';
/** Used for built-in method references. */
var objectProto = Object.prototype;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objectToString = objectProto.toString;
/**
* Checks if `value` is classified as a boolean primitive or object.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isBoolean(false);
* // => true
*
* _.isBoolean(null);
* // => false
*/
function isBoolean(value) {
return value === true || value === false ||
(isObjectLike(value) && objectToString.call(value) == boolTag);
}
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
module.exports = isBoolean;
Creating the Substitution
Template
Begin with the following template for creating the substitution:
'use strict';
const assert = require('assert');
const _ = require('lodash');
function isBoolean() {
// TODO
}
// Assertions
// TODO
Assertions or tests are essential to ensure the validity of your substitution. You can use the examples provided in the comments of the original function. It is also recommended to add additional tests while implementing the substitution to ensure the function behaves as expected.
In this example, we use Lodash as the reference implementation and do not test it against the expected result.
From the comments in the original function, extract the following assertions:
A clear understanding of the original function is crucial:
// isBoolean from lodash
function isBoolean(value) {
return value === true || value === false ||
(isObjectLike(value) && objectToString.call(value) == boolTag);
}
Lodash's isBoolean explicitly compares against true and false. While the typeof operator might seem sufficient, benchmarking shows that explicitly comparing with true and false is faster.
Lodash's isBoolean uses isObjectLike in combination with objectToString. This check is for "instantiated" Boolean objects.
Keep in mind that using objects of primitive types is not recommended. However, for the sake of creating a valid substitution, it's necessary to implement this check. You can add a comment to the substitution, indicating that the check can be removed if the user is sure that no Boolean objects are used.
isObjectLike essentially performs a null check and a typeof check. objectToString is a reference to Object.prototype.toString. The variable boolTag is simply a string reference to the toString result of a Boolean object. You can remove this variable and use the string directly.
The final implementation is as follows:
// isBoolean substitute
function isBoolean(value) {
return (
value === true ||
value === false ||
// not necessary if no Boolean objects are used
(
value && // null check
typeof value === 'object' && // check if it is an object
Object.prototype.toString.call(value) === '[object Boolean]' // check if it is a Boolean object
)
)
}
For the Boolean object branch, include assertions/tests:
'use strict';
const assert = require('assert');
const _ = require('lodash');
function isBoolean(value) {
return (
value === true ||
value === false ||
// Not necessary if no Boolean objects are used
(
value && // Null check
typeof value === 'object' && // Check if it is an object
Object.prototype.toString.call(value) === '[object Boolean]' // Check if it is a Boolean object
)
)
}
// Assertions
assert.strictEqual(_.isBoolean(false), isBoolean(false));
assert.strictEqual(_.isBoolean(null), _.isBoolean(null));
assert.strictEqual(_.isBoolean(true), isBoolean(true));
// Truthy cases
assert.strictEqual(_.isBoolean(Boolean()), isBoolean(Boolean()));
assert.strictEqual(_.isBoolean(Boolean(true)), isBoolean(Boolean(true)));
assert.strictEqual(_.isBoolean(Boolean(false)), is
Boolean(Boolean(false)));
// Instantiated Boolean objects
assert.strictEqual(_.isBoolean(new Boolean(true)), isBoolean(new Boolean(true)));
assert.strictEqual(_.isBoolean(new Boolean(false)), isBoolean(new Boolean(false)));
// Falsy cases
assert.strictEqual(_.isBoolean(new String(true)), isBoolean(new String(true)));
assert.strictEqual(_.isBoolean(new String(false)), isBoolean(new String(false));
Running this code in Node will demonstrate that all assertions pass.
Publishing the Substitution
You can now propose your substitution to the You-Dont-Need-Lodash-Underscore project. You can open an issue to discuss the substitution or create a pull request directly. Follow the patterns outlined in the Readme.md and add your substitution to the appropriate section, listed alphabetically. Use the Lodash website to identify the correct section.
Transform the assertions into Mocha tests in the test/unit/all.js file.
To determine browser support, refer to resources such as the caniuse website or the Mozilla Developer Network.
Creating Valid Substitutions for Lodash Functions
This document provides a comprehensive guide on creating valid substitutions for Lodash functions, using the
_.isBoolean
function as an exemplar.Retrieving the Original Lodash Functionality
Lodash can be complex, with each function residing in its own file. To simplify the process of determining the original functionality, you can utilize per-method packages provided by Lodash. Follow these steps:
code
tab to access the source code of the package, which is bundled in a single file namedindex.js
.Here is the content of the
index.js
for reference:Creating the Substitution
Template
Begin with the following template for creating the substitution:
Assertions or tests are essential to ensure the validity of your substitution. You can use the examples provided in the comments of the original function. It is also recommended to add additional tests while implementing the substitution to ensure the function behaves as expected.
In this example, we use Lodash as the reference implementation and do not test it against the expected result.
From the comments in the original function, extract the following assertions:
Additionally, include the not documented
true
case:Now, let's start with the implementation.
Implementation
A clear understanding of the original function is crucial:
Lodash's
isBoolean
explicitly compares againsttrue
andfalse
. While thetypeof
operator might seem sufficient, benchmarking shows that explicitly comparing withtrue
andfalse
is faster.Lodash's
isBoolean
usesisObjectLike
in combination withobjectToString
. This check is for "instantiated"Boolean
objects.Keep in mind that using objects of primitive types is not recommended. However, for the sake of creating a valid substitution, it's necessary to implement this check. You can add a comment to the substitution, indicating that the check can be removed if the user is sure that no
Boolean
objects are used.isObjectLike
essentially performs a null check and a typeof check.objectToString
is a reference toObject.prototype.toString
. The variableboolTag
is simply a string reference to thetoString
result of aBoolean
object. You can remove this variable and use the string directly.The final implementation is as follows:
For the Boolean object branch, include assertions/tests:
Final Result
Here's the final implementation with assertions:
Running this code in Node will demonstrate that all assertions pass.
Publishing the Substitution
You can now propose your substitution to the You-Dont-Need-Lodash-Underscore project. You can open an issue to discuss the substitution or create a pull request directly. Follow the patterns outlined in the Readme.md and add your substitution to the appropriate section, listed alphabetically. Use the Lodash website to identify the correct section.
Transform the assertions into Mocha tests in the
test/unit/all.js
file.To determine browser support, refer to resources such as the caniuse website or the Mozilla Developer Network.