0.9.3◀Back | Minified | Changelog
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).
Array#indexOf/lastIndexOfpolyfills 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#trimrefactored to handle all characters covered in es5/unicode spec, and added an initial check for support when defining the method
Object.isArraynow an alias
Date#toISOStringchecks for native browser accuracy and adds support accordingly
Date#toISOStringalso when not supported
Function#bindsimilarly checks for browser support and major refactoring to strictly adhere to ES5 spec, including binding functions of inherited classes, etc.
Array#eachis 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/katakanamajorly 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#shiftadded to handle shifting unicode character codes
String#capitalizenow handles a parameter for capitalizing all words in string. This removes the need for
String#caplitalize(which was deprecated) while still maintaining compatibility with Prototype.
String#addrefactored to maintain a parallel with Array#add behavior
String#removeadded as a reciprocal of String#add and a parallel of Array#remove
String#dasherize/underscorefixed a but where it would not strip whitespace
- added new unicode block methods as well as proper documentation which was missing for all
String#pad/Left/Rightrefactored 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
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:
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
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.