What these tests do, is basically constructing Arrays and one Object (in the last test), and then output the data using a “for(var i in array)” loop. All browsers do handle objects and arrays as expected and return the data in the original order, just Google Chrome fails. That means there is no way to store data in a certain order in Chrome, if you don’t want to loop over it with “for(var i = 0; i < array.length; i++)", which can result in significant code and/or processing overhead for a number of reasons.
If all tests are green, they passed. Red results indicate failures:
Especially this comment in JavaScriptCore (Apple Safari), indicates that all browsers should preserve the order of data, as this is a de-facto standard:
// lastIndexUsed is an ever-increasing index used to identify the order items
// were inserted into the property map. It’s required that getEnumerablePropertyNames
// return the properties in the order they were added for compatibility with other
// browsers’ JavaScript implementations.
The ultimate reason behind the behavior of Chrome seems to be that a NumberDictionary is used for certain array/object keys and a StringDictionary for others (handles.cc line 554):
// Compute the element keys.
element_keys = Factory::NewFixedArray(current->NumberOfEnumElements());
current->GetEnumElementKeys(*element_keys);
content = UnionOfKeys(content, element_keys);
content = UnionOfKeys(content, GetEnumPropertyKeys(current));
Also the many type casts do look scary to me =)
Sure you could use non-numeric attributes only, but those are normally part of the inline cache. To cache offsets of arbitrary arrays does not make a lot of sense. The JavaScriptCode devs recognized just that and made it right.
Today, I prepared for the upcoming PHP/JS conferences and had a look at the mysterious bug #883 of Google Chrome and those related to it. Also I read though SquirrelFish source, which is used by Safari 4.
The reason for the odd behavior of Chrome seems to be a if/else construct that is repeated throughout the source of runtime.cc:
// Check if the name is trivially convertible to an index and get
// the element if so.
if (name->AsArrayIndex(&index)) {
return GetElementOrCharAt(object, index);
} else {
PropertyAttributes attr;
return object->GetProperty(*name, &attr);
}
Chrome makes a difference between properties and elements. And they do weird type casts. If you check JavaScriptCore, you see there is a better way:
inline JSValue JSObject::get(ExecState* exec, const Identifier& propertyName) const
{
PropertySlot slot(this);
if (const_cast(this)->getPropertySlot(exec, propertyName, slot))
return slot.getValue(exec, propertyName);
return jsUndefined();
}
Iterating over an objects properties can result in a seemingly random order, it’s always the same order in Chrome, but in a different order for other browsers. I posted this as bug #223 a couple of weeks ago. John Resig posted the same issue as ticket #883 a day later. It was confirmed in the meantime by the chromium developers and described as an expected behavior. Very funny.
I just found my first bug in Chrome: If you iterate over object properties (using jQuery’s $.each()) and insert HTML generated inside that loop into the DOM, then that HTML appears in random order. Very funny. Might be a problem with threads or Chrome changes the order of object properties by itself:
http://code.google.com/p/chromium/issues/detail?id=223
There was a posting re “Mozilla’s Thought On Google’s Chrome” on Slashdot today… which has a comment that underlines what I wrote earlier:
IMHO, the real target is MS Office. Google makes their money from advertising, which means eyeballs and correlated data. Unfortunately for them, many people spend a majority of their day inside MS Word and MS Excel and other apps. Google would love to have those eyeballs and all that data to better shape their profiles and thus better deliver advertising. What better way than to get all those different apps to “occur” inside the browser?
Google will publish a beta version of it’s own Web browser tomorrow. Sadly, the beta will run on Windows only. Of course, they put some energy in speeding up JavaScript execution as they need this for their own applications. Otherwise they simply won’t be able to provide solutions that can compare with traditional offline applications.
For more information check out the online book about Chrome or the Google Blog.
While visiting the Google Blog, I found out, that a JS warning window appears in Firefox 3, if you hit the back button too fast. You’ll see something like this:
SyntaxError: unterminated string literal
w_xa()@:0
eval("try {\n_WidgetManager._HandleControllerResult('Blog1', 'backlinks',{'numBacklinks': [...]
JSONP seems to be unstable in certain conditions. What makes me wonder is why the browser starts to execute incomplete code and outputs that code in an alert dialog. So, it might as well be the fault of the Google Widgets error handler… but who cares anyway.
