Skip to content

Instantly share code, notes, and snippets.

@subzey
Created November 8, 2011 10:51
Show Gist options
  • Save subzey/1347488 to your computer and use it in GitHub Desktop.
Save subzey/1347488 to your computer and use it in GitHub Desktop.
ES5 Whitespace Browser Hell

ES5 Whitespace Browser Hell

Please tell what isFinite('\r\n') is equal to? The right answer is true. Another wtfjs.com case?

The answer why is in ECMA-262 spec, §9.3.1, “ToNumber Applied to the String Type”:

The MV of StringNumericLiteral ::: StrWhiteSpace is 0.

The MV of StringNumericLiteral ::: StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt is the MV of StrNumericLiteral, no matter whether white space is present or not.

where StringNumericLiteral ::: StrWhiteSpace is 1 or more WhiteSpace or LineTerminator. So it's the same as if input string was trimmed. Great!

One of the minor but still important changes in ES5 is adding BOM (Byte order mark) char into WhiteSpace set. My idea was to create very small code snippet in order to detect ES5-compatible browsers/engines.

Here it is:

1-'\ufeff'

Thats it. It should return “truthy” 1 if executed in ES5 and “falsy” NaN if not. Plain and simple and much less than 140byt.es, hehe.

But the practice was ruthless to me.

First of all, I tried it in my fav browser, Opera:

>>> 1-'\ufeff'
NaN

Well, okay, how about that:

>>> 1-'\ufeff'.trim()
1

I was amazed. In one part of Opera's JS engine WhiteSpace does include BOM, and in other part of the same engine it doesn't.

Opera isn't the only browser that amazed me. I've made several tests and here is the result:

Test1-'\ufeff'''.trim && '\ufeff'.trim().length/\s/.test('\ufeff')
Expected in ES510true
Expected in ES3NaNundefinedfalse
Firefox 710false
Opera 11.5, 12.0aNaN0false
Chrome 15NaN1false
IE 910true

In short, Firefox doesn't know that BOM is a whitespace in regexps while accepting it in other cases.

Opera's ToNumber “auto-trim” doesn't work properly, while regular ES5 trim() works perfectly well. And it doesn't include BOM to WhiteSpace when it's about regexp, just like Firefox.

Chrome has plain old ES3 implementation with one exception: ES5 trim() is implemented and it works wrong. Okay, okay, nobody said it's ES5-compatible.

And the winner is Internet Explorer! Crystal-clear ES5 in all three tests. Sounds strange, eh?

That is all. I understand that migration to brave new ES5 world is a long and hard way. But I suppose, it's better to pay your attention now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment