2.0.0◀Back | Minified | Changelog | Cautionlog
After a major hiatus, Sugar 2.0.0 is finally here! This version has been a labor of love. It boasts a completely new way of interacting with the library, massive new features, code modularization, tons of performance optimizations, and a brand new site to match.
- Extending in 2.0.0
- Core Rewrite
- Chainables as Extended Objects
- Modularized Builds
- Sugar as an Ecosystem
- Deep Property Notation
- Date strftime Format
- Array Iteration from an Index
- New Methods
- Renamed Methods
- Removed Methods
- Other Changes
To kick off the new features, beginning in v2.0.0 a companion upgrade script is available to make upgrading easier. This script will monitor your method calls and give information about breaking changes in real-time. See here for more.
Extending in 2.0.0
Although Sugar will continue to have the ability to modify native objects as before, v2.0.0 fundamentally changes this behavior to make it opt-in, and provides two new alternate ways of calling methods. Until now, Sugar was essentially off-limits to library or middleware developers, as extending global objects was something that could not be opted out of. Making this behavior opt-in means that it is no longer a deal breaker for writers of third-party code. Sugar will continue to endorse the safe extension of natives, but in a way that leaves it up to the end user as a choice.
To accomplish this change, Sugar's core has been fundamentally rewritten to
expose a single global object. All interactions with the library now happen
through this object. To begin, all methods are defined as static functions in
namespaces equivalent to their native counterparts, i.e.
Array methods. Instance methods always accept the instance object as their
first argument, while static methods are called the same as before:
The previous behavior of extending natives is now controlled through a global
extend. This method has a number of different options to allow
fine grained control over what methods get extended. Additionally, each
namespace has its own
extend method as well, allowing them to be called
The second new method of interacting with Sugar methods comes in the form of
the "chainable" object. Chainables are constructors that have the exact same
prototype methods as those mapped onto natives with
extend, and so can call
instance methods in the same way. Chainables are easy to remember, because
they are the Sugar namespaces themselves. For example,
Sugar.Array is both
the namespace to call static array methods and also a chainable constructor:
When a chainable is created, it will wrap the native object passed to it as the
first argument. This object can be accessed at any time as the property
All methods called on the chainable object will operate on this object and
return a new chainable that wraps the result, allowing methods to be chained
together. When the time comes to get the result, simply access it with the
value is exposed with
valueOf. Be aware however that this will unwrap the
Chainables as Extended Objects
Previous versions of Sugar included a concept known as "extended objects".
These were a way to circumvent the fact that Sugar does not extend
Object.prototype by having an internal type that mapped Object instance
methods to its own prototype instead. Chainables now replace these – in
fact they are the same concept applied across all native classes. In addition
to previous functionality, chainables also map native methods and are even more
versatile. They include three new methods:
methods by default only return the object's own properties, while excluding
inherited properties. Combined with their new ability to handle deep property
notation (more below), this makes the Object chainable perfect for working with
complex data structures:
Modules in previous versions of Sugar were entire blocks of code that were added or removed together, and only through the site's rather primitive build system. v2.0.0 features a full package dependency model that allows custom builds at the method level. This site will host a build system that makes it easy to create a bundle of any method or date locale available. Even better, npm packages are now fully modularized as well and can also be used to create custom builds with the help of browserify or similar build tools:
Sugar as an Ecosystem
As part of Sugar's modularization, its core functionality has been pulled out into its own npm package. In addition to making the library more modular, the core also exposes an API that allows new methods to be defined. Defining a method will allow interaction in all three forms of use – as a static method on the global, an instance method on a chainable, or in the global namespace in extended mode. All other Sugar modules now go through this API. However, separating the core is even more exciting as it means that third-party developers can author plugins too. Custom Sugar builds can now be composed not only of the Sugar library itself, but other plugins as well. This means that specialized use cases can be delegated to plugins and no longer have to belong to the main library itself.
Deep Property Notation
Sugar methods that accept a string as a reference to an object property can now
refer to deep properties using the dot
. or square bracket
This ability begins with the new
Object.set methods but also
includes methods that allow mapping function shortcuts such as
Array#sortBy, and more. Square bracket
syntax also allows for negative array indexes counted from the end of an array,
and range syntax with
.. to retrieve a subset of an array.
Date strftime format
Date#format now allows strf tokens in addition to
standard "ldml" tokens.
Array Iteration from an Index
Previous versions of Sugar had the ability to iterate over an array starting
from a specific index and, optionally, looping again from the start. However the
implementation was scattered across
Array#findFrom, and usage
was confusing. v2.0.0 cleans this up by providing all ES5 and ES6 methods with
consistently named aliases ending in
FromIndex. All methods are their
"enhanced" versions, and so included mapping/matching shortcuts.
Although performance changes in 2.0.0 vary from method to method, overall this
version has seen the highest attention to performance so far. Date parsing has
seen especially major gains due to major refactoring, and a number of core
methods were reworked as well, including string formatting that feeds
As Sugar is now far more relevant to library and middleware developers than it was before, it will begin strictly following Semver. Previously, MINOR verisions would occasionally have breaking changes. Going forward, a roadmap will be made available on Github, and breaking changes will always prompt a MAJOR version increment.
- Date#get - New date creation with a context date for reference.
- Range#dateUnit - Range date units like Range#years, Range#months, etc.
- Function#memoize - Memoizing expensive function calls
Object.equalsare now both
RegExp#addFlagsand works on multiple.
RegExp#removeFlagsand works on multiple.
String#hasis now native
Object.isNaNis now native
Array#findAllis now aligned with native
Array#includewas removed (now
Object.extendedis now gone in favor of Object chainables which are much more versatile.
Array#allwas removed in favor of
Array#anywas removed in favor of
Object.allwas removed in favor of
Object.anywas removed in favor of
Object.valuesno longer accept a callback.
Object.forEachshould be preferred method of iteration.
Callbacks in object iteration methods like
Object.filter, etc. are now value, key where they were previously key, value. This change helps keep Sugar in line with other libaries as well as keep parity with these methods on Arrays.
Object.isEqualnow handles ES6 objects like Maps, Sets, and Typed Arrays, and is generally more robust.
Object.mergeupdated to handle a number of new options.
Array#sortByhandles sorting on multiple properties.
Number#bytesnow allows normal SI units.
Number.setOptionallows custom thousands and decimal markers.
Date.createtakes a number of new options and replaces clunky APIs like
Object.toQueryStringnow accept an options object that allow customization.
Object.hasnow is much more useful when using objects as data.
Strip#removeTagsnow allow a callback.
String#capitalizehas an extra parameter to downcase the rest of the string.
String#escapeHTMLto double-escape entities.
- Fixed issue with the digit
tenin date creation (Issue #431).
- Fixed issue with the
Date#[unit]Sinceimproperly applying error margins.
- Fixed issue with dates shifting in "monthsFromNow" (and consequently "relative") when traversing into a month that doesn't have enough days.
- Fixed issue with advance/rewind using an object with both a "week" and "day" parameter (Issue #492).
- Fixed issue
Function#everynot being able to cancel itself (Issue #488).
- Fixed issue with German dates not allowing abbreviated weekdays with 2 characters.
- Fixed many issues with DST and simplified month traversal.
- Fixed various date parsing issues (#524, #468, #431, #420).
- Fixed issue with
Object.clonenot handling accessors (#396).
- Fixed issue with
fromQueryStringand empty values (#438).
- Fixed issue with
- Fixed issue with
- Fixed issues with Rhino (#447).
- Fixed issue with