📜 ⬆️ ⬇️

How an error found in the IE9 Platform Preview caused a change in the Javascript standard

image
When we first announced our plans for the pre-release versions of IE9, we said that "developers and people interested in standards and web development will be able to try out the pre-release version of IE9 and make comments and suggestions regarding its work." At the moment we receive daily feedback and use them to improve Internet Explorer 9. However, sometimes feedback is not only about IE9. This story is about how a recent review on the Internet Explorer 9 Platform Preview caused a change in the new JavaScript standard - the 5th edition of EcmaScript .

The EcmaScript 5 standard was officially adopted in December 2009, and the third preliminary version of Internet Explorer 9 is our first most complete implementation. ES5 was designed to remain fully compatible with existing sites, and TC39's technical committee worked to avoid any non-security changes that could render existing JavaScript code inoperable. However, nothing is perfect in the software world, and when we released the third preview version of Internet Explorer 9, we wondered if there were any compatibility issues with existing sites related to ES5.

image
Shortly after the release of the preliminary version of our browser, we received several complaints that some web applications that use jQuery do not work correctly in IE9. We found out that the problem was the following JQuery API method , which in some cases did not work, because the code of the method did not check the user-supplied value for null or undefined before calling Object.prototype.toString . In particular, some of the calls to this jQuery method
isFunction: function ( obj ) {
return toString.call(obj) === "[object Function]" ;
}


* This source code was highlighted with Source Code Highlighter .

terminated by the exception: “TypeError: Object expected” . Further analysis showed that toString is a built-in Object.prototype.toString method that caused a crash when isFunction called it with an undefined value as an argument. Why this exception occurred only in IE9, and not in earlier versions of IE, as well as in browsers from other manufacturers? It is precisely because the behavior of the third pre-release version of IE9 in the standard mode really complies with the ES5 Object.prototype.toString specification.
')
According to the previous EcmaScript specification, calling the built-in method with the null or undefined parameter results in the transfer of a “global object” (for browsers, this is the DOM window object). This opens up a whole host of potential security holes for frameworks whose goal is to make web applications work in safe mode.

The ES5 specification has changed this behavior so that passing null or undefined does not cause the window object to be passed to the function. The definition of each inline method has been updated specifically to solve the problem of getting these values ​​as the value of this . The technical committee attempted to do so in order to maintain backward compatibility for normal use and generate an exception when this is not possible. This created the compatibility issue described above.

This problem can be simply solved by changing the jQuery code:
isFunction: function ( obj ) {
return obj && toString.call(obj) === "[object Function]" ;
},


* This source code was highlighted with Source Code Highlighter .

In fact, the jQuery team plans to make this change. However, this change does not affect the thousands of locally used jQuery libraries existing on the web. Given the high prevalence of jQuery, it becomes obvious that the ES5 specification contains a serious compatibility issue. It is also quite obvious how we can change our implementation of ES5 in IE9 to solve the problem. We can simply return the string value "[object Object]" , the same value returns IE8 in this situation. This fix does not add security problems that ES5 tries to solve. However, we do not want to unilaterally introduce such a difference in our implementation of the new standard. This solution will not help to solve compatibility and interoperability problems if IE corrects this problem in one of the ways, while other browsers do not fix it at all or do it differently.

As soon as we understood the problem and the possible solution, I raised this issue on the mailing list for discussions of the TC39 committee. My first post on this issue was posted at 5:51 pm on Friday June 25th. By 10 pm, replies were received from TC39 members representing Apple, Mozilla, and Google. We all agreed that this was a compatibility issue that needs to be addressed, and the generation of an exception in this case is not necessary and undesirable. Initially, we agreed that the idea of ​​returning a string value, as written in ES3, looks like a good idea for such cases. However, in further discussion on the weekend, we realized that not all browsers currently return "[object Object]" , we also considered the following values "[object Window]" and "[object Global]" .

It was suggested to return "[object null]" and "[object undefined]" . This solution seems to be the best, since it not only eliminates such a problem, as in the case of jQuery, but also makes it possible to clearly distinguish between null and null objects. This solution also increases browser interoperability because it requires browsers to produce the same result, not the ES3 situation, which led to different results in different browsers.

On Tuesday, this decision was taken by consensus as final. Once agreement was reached, I passed the revised Object.prototype.toString specifications to the IE9 JavaScript development team so that they can make corrections to the current implementation before publicly testing the next preview version of IE9. Mozilla also confirmed that it will accept this fix in the next beta version of Firefox. I also updated the TC39 official list of fixes for ES5 , this change is described in section 15.2.4.2 of the specification.

Web standards are complex software artifacts, and like all software, they contain bugs. Sometimes the best way to find and fix a compatibility error is to implement the standard in a widely accepted browser. This method is usually used in the context of the release of earlier versions of the browser, as is the case with Internet Explorer 9 Platform Preview. Thus, when you, as a web developer, send feedback to a specific browser, you also give feedback to the standards that it implements. Of course, in this case, browser authors and standards writers should be able to quickly respond to the problem. A quick response to the ES5 Object.prototype.toString problem, as well as other inconsistencies, is a good example of how browser developers and other TC39 members can and work together to provide a compatible and interoperable web. But it all starts with your feedback, which we always welcome.

-
Allen wirfs-brock
Microsoft JavaScript Language Architect

Source: https://habr.com/ru/post/99652/


All Articles