0.9.3
◀Back | Minified | Changelog2011-08-08
OK, this will be the biggest update since Sugar was released! v0.9.3 makes a major move toward more stability and safety while at the same time adds some nice new features to the library. I've spent the last couple weeks locked in the basement with the ECMAScript 5.1 spec turning it into unit tests to run, and a lot of really good changes and optimizations have come out of it. Here are some highlights (full changelog here).
ES5 compliance:
Array#indexOf/lastIndexOf
polyfills now perform a straight strict equality check on the array. This was causing people trouble in v0.9.1 and patched in v0.9.2. Full unit tests added here.- Polyfills (and their aliases) now throw TypeErrors when required arguments are absent, callbacks not callable, etc.
String#trim
refactored to handle all characters covered in es5/unicode spec, and added an initial check for support when defining the methodArray.isArray
added andObject.isArray
now an aliasDate.now
addedDate#toISOString
checks for native browser accuracy and adds support accordinglyDate#toJSON
similarly aliasesDate#toISOString
also when not supportedFunction#bind
similarly checks for browser support and major refactoring to strictly adhere to ES5 spec, including binding functions of inherited classes, etc.
More sweetness:
Array#each
is now no longer an alias of forEach and has different behavior:- second parameter is the index to start from
- third parameter is a boolean that runs the loop from the beginning if true
- returns the array
- callback returning false will break out of the loop
- will throw a TypeError if fn is not callable (same as forEach)
- array is now passed as the scope as well as the 3rd parameter
- now detects sparse arrays and switches to a different algorithm to handle them
String#hankaku/zenkaku/hiragana/katakana
majorly refactored to use character codes instead of a hash table. This resulted in a much more accurate, less arbitrary mapping as well as 5k total reduction in code!String#shift
added to handle shifting unicode character codesString#capitalize
now handles a parameter for capitalizing all words in string. This removes the need forString#caplitalize
(which was deprecated) while still maintaining compatibility with Prototype.String#add
refactored to maintain a parallel with Array#add behaviorString#remove
added as a reciprocal of String#add and a parallel of Array#removeString#dasherize/underscore
fixed a but where it would not strip whitespace- added new unicode block methods as well as proper documentation which was missing for all
Other changes:
Array#eachFromIndex
removedArray#removeAtIndex
renamed toArray#removeAt
Array#collect
alias removedArray#shuffle
alias removedString#pad/Left/Right
refactored to accept the number as the second param and padding as the first.
About ECMAScript Compliance
As of v0.9.3, Sugar is now fully compliant with ECMAScript Edition 5.1. This was part of a large initiative that began with the method Object.create
which Sugar had initially implemented on its own, and which collided with the ES5 spec. At the time I wasn't aware of everything in the actual spec, discovered the collision just before the initial release of Sugar, and decided to go ahead and release it anyway.
Since then I received a lot of really good feedback and came around to the idea of staying out of the way of the spec. This mostly came from doing my own research, which showed that the spec is fairly conservative in scope, and that by making only a few minor changes I could stay out of its way and still achieve the kind of functionality I wanted for Sugar.
But it didn't stop there. After looking at ES5 in depth I decided that I should really be working alongside the spec rather than simply staying out of its way. In Sugar terms, this basically means providing ES5 standard methods in browsers where they are not natively supported (known as a "polyfill"). The majority of this work had already been done in the form of array methods like forEach
and map
, which were mostly for the sake of IE. Additionally I had begun working on interpreting the spec itself into the unit tests for Sugar. However, it became clear to me that not only should Sugar provide all these methods, but also that the spec itself provides a guide for doing intelligent feature detection to determine if they are properly supported.
At that point compatibility issues with ES5 were limited to the Object.create
method, and an incompatibility with indexOf
. However for full compliance I also decided to add: Object.keys
, Function#bind
, String#trim
, Date.now
, Date#toISOString
, Date#toJSON
, and Array.isArray
. These methods also use feature detection based on the ES5 spec to ensure proper support. One example of the effect this had was that the Sugar unit tests finally began showing a green board in Opera, which up until that point had been failing on Date#toISOString
(the native toISOString
implementation in Opera does not output milliseconds). This tightened feature detection feature in Sugar will now ensure that the polyfills take over not only when the method is missing, but also if it does not properly follow ES5 spec.
Finally, it occurred to me that for full compliance, Sugar should be also providing a polyfill for the method with which it was originally colliding, Object.create
. Unfortunately, this method and others for the Object
native like defineProperty
, seal
, and freeze
provide low-level functionality (such as "freezing" properties and preventing them from appearing in for..in
loops) that simply doesn't exist and can't be replicated in non-compatible browsers, making this essentially as far as Sugar can go.
So to summarize, "full ECMAScript compliance" means 1) zero collisions with ES5 method names, 2) providing all methods in the ES5 spec as polyfills for browsers in which they are not supported, 3) such "support" will be determined by feature detection, which also comes from the ES5 spec, and finally 4) the spec itself is interpreted as unit tests in Sugar, which assure that the polyfill methods behave identically. The only caveat is that such polyfill methods are not provided for Object
, where similar functionality is impossible to achieve in non-compatible browsers.