Posts

Showing posts from October, 2013

The history of “typeof null”

Update 2013-11-05: I take a look at the C code of typeof to better explain why typeof null results in 'object' . In JavaScript, typeof null is 'object' , which incorrectly suggests that null is an object (it isn’t, it’s a primitive value, consult my blog post on categorizing values for details). This is a bug and one that unfortunately can’t be fixed, because it would break existing code. Let’s explore the history of this bug. The “typeof null” bug is a remnant from the first version of JavaScript. In this version, values were stored in 32 bit units, which consisted of a small type tag (1–3 bits) and the actual data of the value. The type tags were stored in the lower bits of the units. There were five of them: 000: object. The data is a reference to an object. 1: int. The data is a 31 bit signed integer. 010: double. The data is a reference to a double floating point number. 100: string. The data is a reference to a string. 110...

The dict pattern: objects without prototypes are better maps

Using objects as maps from strings to values has several pitfalls. This blog post describes a pattern that eliminates some of them. The pitfalls If you are (ab)using objects as maps from strings to values, you’ll encounter several pitfalls: Inherited properties prevent you from directly using the in operator for checking for a key and brackets for reading a value: > var empty = {}; // empty map > var key = 'toString'; > key in empty // should be false true > empty[key] // should be undefined [Function: toString] Map entries override methods, meaning that you can’t directly invoke methods on an object-as-map. You need to escape the key __proto__ , because it triggers special behavior in many JavaScript engines. For details on these pitfalls, consult the blog post “ The pitfalls of using objects as maps in JavaScript ”. The dict pattern The solution is to create an object without a prototype: var dict = Object.cr...

The JavaScript console API

In most JavaScript engines, there is a global object console with methods for logging and debugging. That object is not part of the language proper, but has become a de facto standard, since being pioneered by the Firebug debugger. Since their main purpose is debugging, the console methods will most frequently be used during development and rarely in deployed code. This blog post gives an overview of the methods of console . How standardized is the console API across browsers? Firebug first provided the console API and the documentation in its wiki is the closest thing to a standard there is. Additionally, Brian Kardell and Paul Irish are working on a specification for the API, which should lead to more consistent behavior across browsers in the long term. Until then, behavior varies widely. Therefore, this blog post can only provide an overview. For details, you should consult the following documentation for various platforms: Chrome: developers.google.com/chrome-developer-too...

Safe integers in JavaScript

Update 2014-02-08: Follow-up blog post “ What are integers in JavaScript? ” JavaScript can only safely represent integers i in the range −2 53 < i < 2 53 . This blog post examines why that is and what “safely represent” means. It is based on an email by Mark S. Miller to the es-discuss mailing list. Safe integers The idea of a safe integer is about how mathematical integers are represented in JavaScript. In the range (−2 53 , 2 53 ) (excluding the lower and upper bounds), JavaScript integers are safe : there is a one-to-one mapping between mathematical integers and their representations in JavaScript. Beyond this range, JavaScript integers are unsafe : two or more mathematical integers are represented as the same JavaScript integer. For example, starting at 2 53 , JavaScript can only represent every second mathematical integer. > Math.pow(2, 53) 9007199254740992 > Math.pow(2, 53)+1 9007199254740992 > Math.pow(2, 53)+2 9007199254740994 ...