Rectangle 27 116

OLD only use a reference

First you should(if you have not done this yet) install node.js+npm in 30 seconds (the right way because you should NOT run npm as root):

echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bashrc
. ~/.bashrc
mkdir ~/local
mkdir ~/node-latest-install
cd ~/node-latest-install
curl http://nodejs.org/dist/node-latest.tar.gz | tar xz --strip-components=1
./configure --prefix=~/local
make install # ok, fine, this step probably takes more than 30 seconds...
curl http://npmjs.org/install.sh | sh
npm install express
npm install socket.io
npm install hiredis redis # hiredis to use c binding for redis => FAST :)

You can download complete sample from mediafire.

unzip pbsb.zip # can also do via graphical interface if you prefer.
const PORT = 3000;
const HOST = 'localhost';

var express = require('express');

var app = module.exports = express.createServer();

app.use(express.staticProvider(__dirname + '/public'));

const redis = require('redis');
const client = redis.createClient();

const io = require('socket.io');

if (!module.parent) {
    app.listen(PORT, HOST);
    console.log("Express server listening on port %d", app.address().port)

    const socket  = io.listen(app);

    socket.on('connection', function(client) {
        const subscribe = redis.createClient();
        subscribe.subscribe('pubsub'); //    listen to messages from channel pubsub

        subscribe.on("message", function(channel, message) {
            client.send(message);
        });

        client.on('message', function(msg) {
        });

        client.on('disconnect', function() {
            subscribe.quit();
        });
    });
}
<html>
<head>
    <title>PubSub</title>
    <script src="/socket.io/socket.io.js"></script>
    <script src="/javascripts/jquery-1.4.3.min.js"></script>
</head>
<body>
    <div id="content"></div>
    <script>    
        $(document).ready(function() {
            var socket = new io.Socket('localhost', {port: 3000, rememberTransport: false/*, transports: ['xhr-polling']*/});
            var content = $('#content');

            socket.on('connect', function() {
            });

            socket.on('message', function(message){
                content.prepend(message + '<br />');
            }) ;

            socket.on('disconnect', function() {
                console.log('disconnected');
                content.html("<b>Disconnected!</b>");
            });

            socket.connect();
        });
    </script>
</body>
</html>
cd pbsb    
node app.js

Best if you start google chrome(because of websockets support, but not necessary). Visit http://localhost:3000 to see sample(in the beginning you don't see anything but PubSub as title).

But on publish to channel pubsub you should see a message. Below we publish "Hello world!" to the browser.

publish pubsub "Hello world!"
const client = redis.createClient()

you don't need to use const at all. var could be used as well and maybe I should have instead because const is only available in the newer javascript engines. Furthermore this line ensures we are connected to redis server which we use in this example.

The sample is very old so not up to date with latest socket.io/express modules and maybe even node.js. I would try to update code. There is also another huge problem with this code that it opens another redis connection for each connected user. That should only be on instead. I have to work first, but after that I try to update the code.

javascript - How to use redis PUBLISH/SUBSCRIBE with nodejs to notify ...

javascript node.js redis
Rectangle 27 552

JSON in JavaScript

JSON (JavaScript Object Notation) is a lightweight format that is used for data interchanging.

An example of where this is used is web services responses. In the 'old' days, web services used XML as their primary data format for transmitting back data, but since JSON appeared (The JSON format is specified in RFC 4627 by Douglas Crockford), it has been the preferred format because it is much more lightweight

You can find a lot more info on the official JSON web site.

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

Here is an example of JSON data:

{
     "firstName": "John",
     "lastName": "Smith",
     "address": {
         "streetAddress": "21 2nd Street",
         "city": "New York",
         "state": "NY",
         "postalCode": 10021
     },
     "phoneNumbers": [
         "212 555-1234",
         "646 555-4567"
     ]
 }

When working with JSON and JavaScript, you may be tempted to use the eval function to evaluate the result returned in the callback, but this is not suggested since there are two characters (U+2028 & U+2029) valid in JSON but not in JavaScript (read more of this here).

Therefore, one must always try to use Crockford's script that checks for a valid JSON before evaluating it. Link to the script explanation is found here and here is a direct link to the js file. Every major browser nowadays has its own implementation for this.

Example on how to use the JSON Parser (with the json from the above code snippet):

//The callback function that will be executed once data is received from the server
var callback = function (result) {
    var johnny = JSON.parse(result);
    //Now, the variable 'johnny' is an object that contains all of the properties 
    //from the above code snippet (the json example)
    alert(johnny.firstName + ' ' + johnny.lastName); //Will alert 'John Smith'
};

The JSON Parser also offers another very useful method, stringify. This method accepts a JavaScript object as a parameter, and outputs back a string with JSON format. This is useful for when you want to send data back to the server:

var anObject = {name: "Andreas", surname : "Grech", age : 20};
var jsonFormat = JSON.stringify(anObject);
//The above method will output this: {"name":"Andreas","surname":"Grech","age":20}

The above two methods (parse and stringify) also take a second parameter, which is a function that will be called for every key and value at every level of the final result, and each value will be replaced by result of your inputted function. (More on this here)

Btw, for all of you out there who think JSON is just for JavaScript, check out this post that explains and confirms otherwise.

Regardless of the way information is serialized, you're going to have a parser, right? Therefore, who cares what format you use to transmit data if its implementation details are going to be abstracted away.

Well actually, if you're transmitting data to and fro the client and server, I think it's pretty important to be careful of your response sizes.

For the pedantic, there are a couple of characters that JSON handles differently than JavaScript, preventing it from being a strict subset: timelessrepo.com/json-isnt-a-javascript-subset

Liked the graph very much!

So would you replace XML with JSON? Is that what your saying? If so...Great, xml is a nightmare.

What is JSON and why would I use it? - Stack Overflow

json
Rectangle 27 552

JSON in JavaScript

JSON (JavaScript Object Notation) is a lightweight format that is used for data interchanging.

An example of where this is used is web services responses. In the 'old' days, web services used XML as their primary data format for transmitting back data, but since JSON appeared (The JSON format is specified in RFC 4627 by Douglas Crockford), it has been the preferred format because it is much more lightweight

You can find a lot more info on the official JSON web site.

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

Here is an example of JSON data:

{
     "firstName": "John",
     "lastName": "Smith",
     "address": {
         "streetAddress": "21 2nd Street",
         "city": "New York",
         "state": "NY",
         "postalCode": 10021
     },
     "phoneNumbers": [
         "212 555-1234",
         "646 555-4567"
     ]
 }

When working with JSON and JavaScript, you may be tempted to use the eval function to evaluate the result returned in the callback, but this is not suggested since there are two characters (U+2028 & U+2029) valid in JSON but not in JavaScript (read more of this here).

Therefore, one must always try to use Crockford's script that checks for a valid JSON before evaluating it. Link to the script explanation is found here and here is a direct link to the js file. Every major browser nowadays has its own implementation for this.

Example on how to use the JSON Parser (with the json from the above code snippet):

//The callback function that will be executed once data is received from the server
var callback = function (result) {
    var johnny = JSON.parse(result);
    //Now, the variable 'johnny' is an object that contains all of the properties 
    //from the above code snippet (the json example)
    alert(johnny.firstName + ' ' + johnny.lastName); //Will alert 'John Smith'
};

The JSON Parser also offers another very useful method, stringify. This method accepts a JavaScript object as a parameter, and outputs back a string with JSON format. This is useful for when you want to send data back to the server:

var anObject = {name: "Andreas", surname : "Grech", age : 20};
var jsonFormat = JSON.stringify(anObject);
//The above method will output this: {"name":"Andreas","surname":"Grech","age":20}

The above two methods (parse and stringify) also take a second parameter, which is a function that will be called for every key and value at every level of the final result, and each value will be replaced by result of your inputted function. (More on this here)

Btw, for all of you out there who think JSON is just for JavaScript, check out this post that explains and confirms otherwise.

Regardless of the way information is serialized, you're going to have a parser, right? Therefore, who cares what format you use to transmit data if its implementation details are going to be abstracted away.

Well actually, if you're transmitting data to and fro the client and server, I think it's pretty important to be careful of your response sizes.

For the pedantic, there are a couple of characters that JSON handles differently than JavaScript, preventing it from being a strict subset: timelessrepo.com/json-isnt-a-javascript-subset

Liked the graph very much!

So would you replace XML with JSON? Is that what your saying? If so...Great, xml is a nightmare.

What is JSON and why would I use it? - Stack Overflow

json
Rectangle 27 548

JSON in JavaScript

JSON (JavaScript Object Notation) is a lightweight format that is used for data interchanging.

An example of where this is used is web services responses. In the 'old' days, web services used XML as their primary data format for transmitting back data, but since JSON appeared (The JSON format is specified in RFC 4627 by Douglas Crockford), it has been the preferred format because it is much more lightweight

You can find a lot more info on the official JSON web site.

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

Here is an example of JSON data:

{
     "firstName": "John",
     "lastName": "Smith",
     "address": {
         "streetAddress": "21 2nd Street",
         "city": "New York",
         "state": "NY",
         "postalCode": 10021
     },
     "phoneNumbers": [
         "212 555-1234",
         "646 555-4567"
     ]
 }

When working with JSON and JavaScript, you may be tempted to use the eval function to evaluate the result returned in the callback, but this is not suggested since there are two characters (U+2028 & U+2029) valid in JSON but not in JavaScript (read more of this here).

Therefore, one must always try to use Crockford's script that checks for a valid JSON before evaluating it. Link to the script explanation is found here and here is a direct link to the js file. Every major browser nowadays has its own implementation for this.

Example on how to use the JSON Parser (with the json from the above code snippet):

//The callback function that will be executed once data is received from the server
var callback = function (result) {
    var johnny = JSON.parse(result);
    //Now, the variable 'johnny' is an object that contains all of the properties 
    //from the above code snippet (the json example)
    alert(johnny.firstName + ' ' + johnny.lastName); //Will alert 'John Smith'
};

The JSON Parser also offers another very useful method, stringify. This method accepts a JavaScript object as a parameter, and outputs back a string with JSON format. This is useful for when you want to send data back to the server:

var anObject = {name: "Andreas", surname : "Grech", age : 20};
var jsonFormat = JSON.stringify(anObject);
//The above method will output this: {"name":"Andreas","surname":"Grech","age":20}

The above two methods (parse and stringify) also take a second parameter, which is a function that will be called for every key and value at every level of the final result, and each value will be replaced by result of your inputted function. (More on this here)

Btw, for all of you out there who think JSON is just for JavaScript, check out this post that explains and confirms otherwise.

Regardless of the way information is serialized, you're going to have a parser, right? Therefore, who cares what format you use to transmit data if its implementation details are going to be abstracted away.

Well actually, if you're transmitting data to and fro the client and server, I think it's pretty important to be careful of your response sizes.

For the pedantic, there are a couple of characters that JSON handles differently than JavaScript, preventing it from being a strict subset: timelessrepo.com/json-isnt-a-javascript-subset

Liked the graph very much!

So would you replace XML with JSON? Is that what your saying? If so...Great, xml is a nightmare.

What is JSON and why would I use it? - Stack Overflow

json
Rectangle 27 548

JSON in JavaScript

JSON (JavaScript Object Notation) is a lightweight format that is used for data interchanging.

An example of where this is used is web services responses. In the 'old' days, web services used XML as their primary data format for transmitting back data, but since JSON appeared (The JSON format is specified in RFC 4627 by Douglas Crockford), it has been the preferred format because it is much more lightweight

You can find a lot more info on the official JSON web site.

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

Here is an example of JSON data:

{
     "firstName": "John",
     "lastName": "Smith",
     "address": {
         "streetAddress": "21 2nd Street",
         "city": "New York",
         "state": "NY",
         "postalCode": 10021
     },
     "phoneNumbers": [
         "212 555-1234",
         "646 555-4567"
     ]
 }

When working with JSON and JavaScript, you may be tempted to use the eval function to evaluate the result returned in the callback, but this is not suggested since there are two characters (U+2028 & U+2029) valid in JSON but not in JavaScript (read more of this here).

Therefore, one must always try to use Crockford's script that checks for a valid JSON before evaluating it. Link to the script explanation is found here and here is a direct link to the js file. Every major browser nowadays has its own implementation for this.

Example on how to use the JSON Parser (with the json from the above code snippet):

//The callback function that will be executed once data is received from the server
var callback = function (result) {
    var johnny = JSON.parse(result);
    //Now, the variable 'johnny' is an object that contains all of the properties 
    //from the above code snippet (the json example)
    alert(johnny.firstName + ' ' + johnny.lastName); //Will alert 'John Smith'
};

The JSON Parser also offers another very useful method, stringify. This method accepts a JavaScript object as a parameter, and outputs back a string with JSON format. This is useful for when you want to send data back to the server:

var anObject = {name: "Andreas", surname : "Grech", age : 20};
var jsonFormat = JSON.stringify(anObject);
//The above method will output this: {"name":"Andreas","surname":"Grech","age":20}

The above two methods (parse and stringify) also take a second parameter, which is a function that will be called for every key and value at every level of the final result, and each value will be replaced by result of your inputted function. (More on this here)

Btw, for all of you out there who think JSON is just for JavaScript, check out this post that explains and confirms otherwise.

Regardless of the way information is serialized, you're going to have a parser, right? Therefore, who cares what format you use to transmit data if its implementation details are going to be abstracted away.

Well actually, if you're transmitting data to and fro the client and server, I think it's pretty important to be careful of your response sizes.

For the pedantic, there are a couple of characters that JSON handles differently than JavaScript, preventing it from being a strict subset: timelessrepo.com/json-isnt-a-javascript-subset

Liked the graph very much!

So would you replace XML with JSON? Is that what your saying? If so...Great, xml is a nightmare.

What is JSON and why would I use it? - Stack Overflow

json
Rectangle 27 5549

2. Use a simple for loop

  • Don't use for-in unless you use it with safeguards or are at least aware of why it might bite you.
  • a for-of loop (ES2015+ only),
  • Array#forEach (spec | MDN) (or its relatives some and such) (ES5+ only),
  • a simple old-fashioned for loop,
  • or for-in with safeguards.

JavaScript has powerful semantics for looping through arrays and array-like objects. I've split the answer into two parts: Options for genuine arrays, and options for things that are just array-like, such as the arguments object, other iterable objects (ES2015+), DOM collections, and so on.

I'll quickly note that you can use the ES2015 options now, even on ES5 engines, by transpiling ES2015 to ES5. Search for "ES2015 transpiling" / "ES6 transpiling" for more...

You have three options in ECMAScript5 ("ES5"), the version most broadly supported at the moment, and will soon have two more in ECMAScript2015 ("ES2015", "ES6"), the latest version of JavaScript that vendors are working on supporting:

  • Use a simple for loop

If you're using an environment that supports the Array features of ES5 (directly or using a shim), you can use the new forEach (spec | MDN):

var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});

forEach accepts an iterator function and, optionally, a value to use as this when calling that iterator function (not used above). The iterator function is called for each entry in the array, in order, skipping non-existent entries in sparse arrays. Although I only used one argument above, the iterator function is called with three: The value of each entry, the index of that entry, and a reference to the array you're iterating over (in case your function doesn't already have it handy).

Unless you're supporting obsolete browsers like IE8 (which NetApps shows at just over 4% market share as of this writing in September2016), you can happily use forEach in a general-purpose web page without a shim. If you do need to support obsolete browsers, shimming/polyfilling forEach is easily done (search for "es5 shim" for several options).

forEach has the benefit that you don't have to declare indexing and value variables in the containing scope, as they're supplied as arguments to the iteration function, and so nicely scoped to just that iteration.

If you're worried about the runtime cost of making a function call for each array entry, don't be; details.

Additionally, forEach is the "loop through them all" function, but ES5 defined several other useful "work your way through the array and do things" functions, including:

  • every (stops looping the first time the iterator returns false or something falsey)
  • some (stops looping the first time the iterator returns true or something truthy)
  • filter (creates a new array including elements where the filter function returns true and omitting the ones where it returns false)
  • map (creates a new array from the values returned by the iterator function)
  • reduce (builds up a value by repeated calling the iterator, passing in previous values; see the spec for the details; useful for summing the contents of an array and many other things)
reduceRight
reduce

Sometimes the old ways are the best:

If the length of the array won't change during the loop, and it's in performance-sensitive code (unlikely), a slightly more complicated version grabbing the length up front might be a tiny bit faster:

var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}
var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}

But with modern JavaScript engines, it's rare you need to eke out that last bit of juice.

In ES2015 and higher, you can make your index and value variables local to the for loop:

let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
}
//console.log(index); // Would cause "ReferenceError: index is not defined"
//console.log(value); // Would cause "ReferenceError: value is not defined"

And when you do that, not just value but also index is recreated for each loop iteration, meaning closures created in the loop body keep a reference to the index (and value) created for that specific iteration:

let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        alert("Index is: " + index);
    });
}

If you had five divs, you'd get "Index is: 0" if you clicked the first and "Index is: 4" if you clicked the last. This does not work if you use var instead of let.

You'll get people telling you to use for-in, but that's not what for-in is for. for-in loops through the enumerable properties of an object, not the indexes of an array. The order is not guaranteed, not even in ES2015 (ES6). ES2015 does define an order to object properties (via [[OwnPropertyKeys]], [[Enumerate]], and things that use them like Object.getOwnPropertyKeys), but it does not define that for-in will follow that order. (Details in this other answer.)

Still, it can be useful, particularly for sparse arrays, if you use appropriate safeguards:

// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These are explained
        /^0$|^[1-9]\d*$/.test(key) &&    // and then hidden
        key <= 4294967294                // away below
        ) {
        console.log(a[key]);
    }
}

Note the two checks:

That's a tiny bit of added overhead per loop iteration on most arrays, but if you have a sparse array, it can be a more efficient way to loop because it only loops for entries that actually exist. E.g., for the array above, we loop a total of three times (for keys "0", "10", and "10000" remember, they're strings), not 10,001 times.

Now, you won't want to write that every time, so you might put this in your toolkit:

function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) && /^0$|^[1-9]\d*$/.test(prop) && prop <= 4294967294; // 2^32 - 2
}
for (key in a) {
    if (arrayHasOwnIndex(a, key)) {
        console.log(a[key]);
    }
}

Or if you're interested in just a "good enough for most cases" test, you could use this, but while it's close, it's not quite correct:

for (key in a) {
    // "Good enough" for most cases
    if (String(parseInt(key, 10)) === key && a.hasOwnProperty(key)) {
        console.log(a[key]);
    }
}

ES2015 adds iterators to JavaScript. The easiest way to use iterators is the new for-of statement. It looks like this:

var val;
var a = ["a", "b", "c"];
for (val of a) {
    console.log(val);
}

Under the covers, that gets an iterator from the array and loops through it, getting the values from it. This doesn't have the issue that using for-in has, because it uses an iterator defined by the object (the array), and arrays define that their iterators iterate through their entries (not their properties). Unlike for-in in ES5, the order in which the entries are visited is the numeric order of their indexes.

Sometimes, you might want to use an iterator explicitly. You can do that, too, although it's a lot clunkier than for-of. It looks like this:

var a = ["a", "b", "c"];
var it = a.values();
var entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}

The iterator is a function (specifically, a generator) that returns a new object each time you call next. The object returned by the iterator has a property, done, telling us whether it's done, and a property value with the value for that iteration.

The meaning of value varies depending on the iterator; arrays support (at least) three functions that return iterators:

  • values(): This is the one I used above. It returns an iterator where each value is the value for that iteration.
  • keys(): Returns an iterator where each value is the key for that iteration (so for our a above, that would be "0", then "1", then "2").
  • entries(): Returns an iterator where each value is an array in the form [key, value] for that iteration.

(As of this writing, Firefox 29 supports entries and keys but not values.)

Aside from true arrays, there are also array-like objects that have a length property and properties with numeric names: NodeList instances, the arguments object, etc. How do we loop through their contents?

At least some, and possibly most or even all, of the array approaches above frequently apply equally well to array-like objects:

The various functions on Array.prototype are "intentionally generic" and can usually be used on array-like objects via Function#call or Function#apply. (See the Caveat for host-provided objects at the end of this answer, but it's a rare issue.)

forEach
Node
childNodes
Array.prototype.forEach.call(node.childNodes, function(child) {
    // Do something with `child`
});

If you're going to do that a lot, you might want to grab a copy of the function reference into a variable for reuse, e.g.:

// (This is all presumably in some scoping function)
var forEach = Array.prototype.forEach;

// Then later...
forEach.call(node.childNodes, function(child) {
    // Do something with `child`
});

Use a simple for loop

Obviously, a simple for loop applies to array-like objects.

for-in

for-in with the same safeguards as with an array should work with array-like objects as well; the caveat for host-provided objects on #1 above may apply.

for-of

for-of will use the iterator provided by the object (if any); we'll have to see how this plays with the various array-like objects, particularly host-provided ones.

Other times, you may want to convert an array-like object into a true array. Doing that is surprisingly easy:

Use the slice method of arrays

We can use the slice method of arrays, which like the other methods mentioned above is "intentionally generic" and so can be used with array-like objects, like this:

var trueArray = Array.prototype.slice.call(arrayLikeObject);
var divs = Array.prototype.slice.call(document.querySelectorAll("div"));

See the Caveat for host-provided objects below. In particular, note that this will fail in IE8 and earlier, which don't let you use host-provided objects as this like that.

...

It's also possible to use ES2015's spread notation (MDN currently calls it an operator; it isn't one), with JavaScript engines that support this feature:

var trueArray = [...iterableObject];

So for instance, if we want to convert a NodeList into a true array, with spread syntax this becomes quite succinct:

var divs = [...document.querySelectorAll("div")];
Array.from

Array.from (ES2015, but shimmable) creates an array from an array-like object, optionally passing the entries through a mapping function first. So:

var divs = Array.from(document.querySelectorAll("div"));

Or if you wanted to get an array of the tag names of the elements with a given class, you'd use the mapping function:

// Arrow function (ES2015):
var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName);

// Standard function (since `Array.from` can be shimmed):
var divs = Array.from(document.querySelectorAll(".some-class"), function(element) {
    return element.tagName;
});

If you use Array.prototype functions with host-provided array-like objects (DOM lists and other things provided by the browser rather than the JavaScript engine), you need to be sure to test in your target environments to make sure the host-provided object behaves properly. Most do behave properly (now), but it's important to test. The reason is that most of the Array.prototype methods you're likely to want to use rely on the host-provided object giving an honest answer to the abstract [[HasProperty]] operation. As of this writing, browsers do a very good job of this, but the ES5 spec did allow for the possibility a host-provided object may not be honest; it's in 8.6.2 (several paragraphs below the big table near the beginning of that section), where it says:

Host objects may implement these internal methods in any manner unless specified otherwise; for example, one possibility is that [[Get]] and [[Put]] for a particular host object indeed fetch and store property values but [[HasProperty]] always generates false.

(I couldn't find the equivalent verbiage in the ES2015 spec, but it's bound to still be the case.) Again, as of this writing the common host-provided array-like objects in modern browsers (NodeList instances, for instance) do handle [[HasProperty]] correctly, but it's important to test.

I would also like to add that .forEach cannot be broken efficiently. You have to throw an exception to perform the break.

@Pius: If you want to break the loop, you can use some. (I would have preferred allowing breaking forEach as well, but they, um, didn't ask me. ;-) )

@T.J.Crowder True, even though it looks more like a work-around as it's not its primary purpose.

@user889030: You need a , after k=0, not a ;. Remember, programming is many things, one of which is close attention to detail... :-)

@JimB: That's covered above (and length isn't a method). :-)

For-each over an array in JavaScript? - Stack Overflow

javascript arrays loops foreach iteration
Rectangle 27 5493

2. Use a simple for loop

  • Don't use for-in unless you use it with safeguards or are at least aware of why it might bite you.
  • a for-of loop (ES2015+ only),
  • Array#forEach (spec | MDN) (or its relatives some and such) (ES5+ only),
  • a simple old-fashioned for loop,
  • or for-in with safeguards.

JavaScript has powerful semantics for looping through arrays and array-like objects. I've split the answer into two parts: Options for genuine arrays, and options for things that are just array-like, such as the arguments object, other iterable objects (ES2015+), DOM collections, and so on.

I'll quickly note that you can use the ES2015 options now, even on ES5 engines, by transpiling ES2015 to ES5. Search for "ES2015 transpiling" / "ES6 transpiling" for more...

You have three options in ECMAScript5 ("ES5"), the version most broadly supported at the moment, and will soon have two more in ECMAScript2015 ("ES2015", "ES6"), the latest version of JavaScript that vendors are working on supporting:

  • Use a simple for loop

If you're using an environment that supports the Array features of ES5 (directly or using a shim), you can use the new forEach (spec | MDN):

var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});

forEach accepts an iterator function and, optionally, a value to use as this when calling that iterator function (not used above). The iterator function is called for each entry in the array, in order, skipping non-existent entries in sparse arrays. Although I only used one argument above, the iterator function is called with three: The value of each entry, the index of that entry, and a reference to the array you're iterating over (in case your function doesn't already have it handy).

Unless you're supporting obsolete browsers like IE8 (which NetApps shows at just over 4% market share as of this writing in September2016), you can happily use forEach in a general-purpose web page without a shim. If you do need to support obsolete browsers, shimming/polyfilling forEach is easily done (search for "es5 shim" for several options).

forEach has the benefit that you don't have to declare indexing and value variables in the containing scope, as they're supplied as arguments to the iteration function, and so nicely scoped to just that iteration.

If you're worried about the runtime cost of making a function call for each array entry, don't be; details.

Additionally, forEach is the "loop through them all" function, but ES5 defined several other useful "work your way through the array and do things" functions, including:

  • every (stops looping the first time the iterator returns false or something falsey)
  • some (stops looping the first time the iterator returns true or something truthy)
  • filter (creates a new array including elements where the filter function returns true and omitting the ones where it returns false)
  • map (creates a new array from the values returned by the iterator function)
  • reduce (builds up a value by repeated calling the iterator, passing in previous values; see the spec for the details; useful for summing the contents of an array and many other things)
reduceRight
reduce

Sometimes the old ways are the best:

If the length of the array won't change during the loop, and it's in performance-sensitive code (unlikely), a slightly more complicated version grabbing the length up front might be a tiny bit faster:

var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}
var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}

But with modern JavaScript engines, it's rare you need to eke out that last bit of juice.

In ES2015 and higher, you can make your index and value variables local to the for loop:

let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
}
//console.log(index); // Would cause "ReferenceError: index is not defined"
//console.log(value); // Would cause "ReferenceError: value is not defined"

And when you do that, not just value but also index is recreated for each loop iteration, meaning closures created in the loop body keep a reference to the index (and value) created for that specific iteration:

let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        alert("Index is: " + index);
    });
}

If you had five divs, you'd get "Index is: 0" if you clicked the first and "Index is: 4" if you clicked the last. This does not work if you use var instead of let.

You'll get people telling you to use for-in, but that's not what for-in is for. for-in loops through the enumerable properties of an object, not the indexes of an array. The order is not guaranteed, not even in ES2015 (ES6). ES2015 does define an order to object properties (via [[OwnPropertyKeys]], [[Enumerate]], and things that use them like Object.getOwnPropertyKeys), but it does not define that for-in will follow that order. (Details in this other answer.)

Still, it can be useful, particularly for sparse arrays, if you use appropriate safeguards:

// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These are explained
        /^0$|^[1-9]\d*$/.test(key) &&    // and then hidden
        key <= 4294967294                // away below
        ) {
        console.log(a[key]);
    }
}

Note the two checks:

That's a tiny bit of added overhead per loop iteration on most arrays, but if you have a sparse array, it can be a more efficient way to loop because it only loops for entries that actually exist. E.g., for the array above, we loop a total of three times (for keys "0", "10", and "10000" remember, they're strings), not 10,001 times.

Now, you won't want to write that every time, so you might put this in your toolkit:

function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) && /^0$|^[1-9]\d*$/.test(prop) && prop <= 4294967294; // 2^32 - 2
}
for (key in a) {
    if (arrayHasOwnIndex(a, key)) {
        console.log(a[key]);
    }
}

Or if you're interested in just a "good enough for most cases" test, you could use this, but while it's close, it's not quite correct:

for (key in a) {
    // "Good enough" for most cases
    if (String(parseInt(key, 10)) === key && a.hasOwnProperty(key)) {
        console.log(a[key]);
    }
}

ES2015 adds iterators to JavaScript. The easiest way to use iterators is the new for-of statement. It looks like this:

var val;
var a = ["a", "b", "c"];
for (val of a) {
    console.log(val);
}

Under the covers, that gets an iterator from the array and loops through it, getting the values from it. This doesn't have the issue that using for-in has, because it uses an iterator defined by the object (the array), and arrays define that their iterators iterate through their entries (not their properties). Unlike for-in in ES5, the order in which the entries are visited is the numeric order of their indexes.

Sometimes, you might want to use an iterator explicitly. You can do that, too, although it's a lot clunkier than for-of. It looks like this:

var a = ["a", "b", "c"];
var it = a.values();
var entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}

The iterator is a function (specifically, a generator) that returns a new object each time you call next. The object returned by the iterator has a property, done, telling us whether it's done, and a property value with the value for that iteration.

The meaning of value varies depending on the iterator; arrays support (at least) three functions that return iterators:

  • values(): This is the one I used above. It returns an iterator where each value is the value for that iteration.
  • keys(): Returns an iterator where each value is the key for that iteration (so for our a above, that would be "0", then "1", then "2").
  • entries(): Returns an iterator where each value is an array in the form [key, value] for that iteration.

(As of this writing, Firefox 29 supports entries and keys but not values.)

Aside from true arrays, there are also array-like objects that have a length property and properties with numeric names: NodeList instances, the arguments object, etc. How do we loop through their contents?

At least some, and possibly most or even all, of the array approaches above frequently apply equally well to array-like objects:

The various functions on Array.prototype are "intentionally generic" and can usually be used on array-like objects via Function#call or Function#apply. (See the Caveat for host-provided objects at the end of this answer, but it's a rare issue.)

forEach
Node
childNodes
Array.prototype.forEach.call(node.childNodes, function(child) {
    // Do something with `child`
});

If you're going to do that a lot, you might want to grab a copy of the function reference into a variable for reuse, e.g.:

// (This is all presumably in some scoping function)
var forEach = Array.prototype.forEach;

// Then later...
forEach.call(node.childNodes, function(child) {
    // Do something with `child`
});

Use a simple for loop

Obviously, a simple for loop applies to array-like objects.

for-in

for-in with the same safeguards as with an array should work with array-like objects as well; the caveat for host-provided objects on #1 above may apply.

for-of

for-of will use the iterator provided by the object (if any); we'll have to see how this plays with the various array-like objects, particularly host-provided ones.

Other times, you may want to convert an array-like object into a true array. Doing that is surprisingly easy:

Use the slice method of arrays

We can use the slice method of arrays, which like the other methods mentioned above is "intentionally generic" and so can be used with array-like objects, like this:

var trueArray = Array.prototype.slice.call(arrayLikeObject);
var divs = Array.prototype.slice.call(document.querySelectorAll("div"));

See the Caveat for host-provided objects below. In particular, note that this will fail in IE8 and earlier, which don't let you use host-provided objects as this like that.

...

It's also possible to use ES2015's spread notation (MDN currently calls it an operator; it isn't one), with JavaScript engines that support this feature:

var trueArray = [...iterableObject];

So for instance, if we want to convert a NodeList into a true array, with spread syntax this becomes quite succinct:

var divs = [...document.querySelectorAll("div")];
Array.from

Array.from (ES2015, but shimmable) creates an array from an array-like object, optionally passing the entries through a mapping function first. So:

var divs = Array.from(document.querySelectorAll("div"));

Or if you wanted to get an array of the tag names of the elements with a given class, you'd use the mapping function:

// Arrow function (ES2015):
var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName);

// Standard function (since `Array.from` can be shimmed):
var divs = Array.from(document.querySelectorAll(".some-class"), function(element) {
    return element.tagName;
});

If you use Array.prototype functions with host-provided array-like objects (DOM lists and other things provided by the browser rather than the JavaScript engine), you need to be sure to test in your target environments to make sure the host-provided object behaves properly. Most do behave properly (now), but it's important to test. The reason is that most of the Array.prototype methods you're likely to want to use rely on the host-provided object giving an honest answer to the abstract [[HasProperty]] operation. As of this writing, browsers do a very good job of this, but the ES5 spec did allow for the possibility a host-provided object may not be honest; it's in 8.6.2 (several paragraphs below the big table near the beginning of that section), where it says:

Host objects may implement these internal methods in any manner unless specified otherwise; for example, one possibility is that [[Get]] and [[Put]] for a particular host object indeed fetch and store property values but [[HasProperty]] always generates false.

(I couldn't find the equivalent verbiage in the ES2015 spec, but it's bound to still be the case.) Again, as of this writing the common host-provided array-like objects in modern browsers (NodeList instances, for instance) do handle [[HasProperty]] correctly, but it's important to test.

I would also like to add that .forEach cannot be broken efficiently. You have to throw an exception to perform the break.

@Pius: If you want to break the loop, you can use some. (I would have preferred allowing breaking forEach as well, but they, um, didn't ask me. ;-) )

@T.J.Crowder True, even though it looks more like a work-around as it's not its primary purpose.

@user889030: You need a , after k=0, not a ;. Remember, programming is many things, one of which is close attention to detail... :-)

@JimB: That's covered above (and length isn't a method). :-)

For-each over an array in JavaScript? - Stack Overflow

javascript arrays loops foreach iteration
Rectangle 27 5484

2. Use a simple for loop

  • Don't use for-in unless you use it with safeguards or are at least aware of why it might bite you.
  • a for-of loop (ES2015+ only),
  • Array#forEach (spec | MDN) (or its relatives some and such) (ES5+ only),
  • a simple old-fashioned for loop,
  • or for-in with safeguards.

JavaScript has powerful semantics for looping through arrays and array-like objects. I've split the answer into two parts: Options for genuine arrays, and options for things that are just array-like, such as the arguments object, other iterable objects (ES2015+), DOM collections, and so on.

I'll quickly note that you can use the ES2015 options now, even on ES5 engines, by transpiling ES2015 to ES5. Search for "ES2015 transpiling" / "ES6 transpiling" for more...

You have three options in ECMAScript5 ("ES5"), the version most broadly supported at the moment, and will soon have two more in ECMAScript2015 ("ES2015", "ES6"), the latest version of JavaScript that vendors are working on supporting:

  • Use a simple for loop

If you're using an environment that supports the Array features of ES5 (directly or using a shim), you can use the new forEach (spec | MDN):

var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});

forEach accepts an iterator function and, optionally, a value to use as this when calling that iterator function (not used above). The iterator function is called for each entry in the array, in order, skipping non-existent entries in sparse arrays. Although I only used one argument above, the iterator function is called with three: The value of each entry, the index of that entry, and a reference to the array you're iterating over (in case your function doesn't already have it handy).

Unless you're supporting obsolete browsers like IE8 (which NetApps shows at just over 4% market share as of this writing in September2016), you can happily use forEach in a general-purpose web page without a shim. If you do need to support obsolete browsers, shimming/polyfilling forEach is easily done (search for "es5 shim" for several options).

forEach has the benefit that you don't have to declare indexing and value variables in the containing scope, as they're supplied as arguments to the iteration function, and so nicely scoped to just that iteration.

If you're worried about the runtime cost of making a function call for each array entry, don't be; details.

Additionally, forEach is the "loop through them all" function, but ES5 defined several other useful "work your way through the array and do things" functions, including:

  • every (stops looping the first time the iterator returns false or something falsey)
  • some (stops looping the first time the iterator returns true or something truthy)
  • filter (creates a new array including elements where the filter function returns true and omitting the ones where it returns false)
  • map (creates a new array from the values returned by the iterator function)
  • reduce (builds up a value by repeated calling the iterator, passing in previous values; see the spec for the details; useful for summing the contents of an array and many other things)
reduceRight
reduce

Sometimes the old ways are the best:

If the length of the array won't change during the loop, and it's in performance-sensitive code (unlikely), a slightly more complicated version grabbing the length up front might be a tiny bit faster:

var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}
var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}

But with modern JavaScript engines, it's rare you need to eke out that last bit of juice.

In ES2015 and higher, you can make your index and value variables local to the for loop:

let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
}
//console.log(index); // Would cause "ReferenceError: index is not defined"
//console.log(value); // Would cause "ReferenceError: value is not defined"

And when you do that, not just value but also index is recreated for each loop iteration, meaning closures created in the loop body keep a reference to the index (and value) created for that specific iteration:

let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        alert("Index is: " + index);
    });
}

If you had five divs, you'd get "Index is: 0" if you clicked the first and "Index is: 4" if you clicked the last. This does not work if you use var instead of let.

You'll get people telling you to use for-in, but that's not what for-in is for. for-in loops through the enumerable properties of an object, not the indexes of an array. The order is not guaranteed, not even in ES2015 (ES6). ES2015 does define an order to object properties (via [[OwnPropertyKeys]], [[Enumerate]], and things that use them like Object.getOwnPropertyKeys), but it does not define that for-in will follow that order. (Details in this other answer.)

Still, it can be useful, particularly for sparse arrays, if you use appropriate safeguards:

// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These are explained
        /^0$|^[1-9]\d*$/.test(key) &&    // and then hidden
        key <= 4294967294                // away below
        ) {
        console.log(a[key]);
    }
}

Note the two checks:

That's a tiny bit of added overhead per loop iteration on most arrays, but if you have a sparse array, it can be a more efficient way to loop because it only loops for entries that actually exist. E.g., for the array above, we loop a total of three times (for keys "0", "10", and "10000" remember, they're strings), not 10,001 times.

Now, you won't want to write that every time, so you might put this in your toolkit:

function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) && /^0$|^[1-9]\d*$/.test(prop) && prop <= 4294967294; // 2^32 - 2
}
for (key in a) {
    if (arrayHasOwnIndex(a, key)) {
        console.log(a[key]);
    }
}

Or if you're interested in just a "good enough for most cases" test, you could use this, but while it's close, it's not quite correct:

for (key in a) {
    // "Good enough" for most cases
    if (String(parseInt(key, 10)) === key && a.hasOwnProperty(key)) {
        console.log(a[key]);
    }
}

ES2015 adds iterators to JavaScript. The easiest way to use iterators is the new for-of statement. It looks like this:

var val;
var a = ["a", "b", "c"];
for (val of a) {
    console.log(val);
}

Under the covers, that gets an iterator from the array and loops through it, getting the values from it. This doesn't have the issue that using for-in has, because it uses an iterator defined by the object (the array), and arrays define that their iterators iterate through their entries (not their properties). Unlike for-in in ES5, the order in which the entries are visited is the numeric order of their indexes.

Sometimes, you might want to use an iterator explicitly. You can do that, too, although it's a lot clunkier than for-of. It looks like this:

var a = ["a", "b", "c"];
var it = a.values();
var entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}

The iterator is a function (specifically, a generator) that returns a new object each time you call next. The object returned by the iterator has a property, done, telling us whether it's done, and a property value with the value for that iteration.

The meaning of value varies depending on the iterator; arrays support (at least) three functions that return iterators:

  • values(): This is the one I used above. It returns an iterator where each value is the value for that iteration.
  • keys(): Returns an iterator where each value is the key for that iteration (so for our a above, that would be "0", then "1", then "2").
  • entries(): Returns an iterator where each value is an array in the form [key, value] for that iteration.

(As of this writing, Firefox 29 supports entries and keys but not values.)

Aside from true arrays, there are also array-like objects that have a length property and properties with numeric names: NodeList instances, the arguments object, etc. How do we loop through their contents?

At least some, and possibly most or even all, of the array approaches above frequently apply equally well to array-like objects:

The various functions on Array.prototype are "intentionally generic" and can usually be used on array-like objects via Function#call or Function#apply. (See the Caveat for host-provided objects at the end of this answer, but it's a rare issue.)

forEach
Node
childNodes
Array.prototype.forEach.call(node.childNodes, function(child) {
    // Do something with `child`
});

If you're going to do that a lot, you might want to grab a copy of the function reference into a variable for reuse, e.g.:

// (This is all presumably in some scoping function)
var forEach = Array.prototype.forEach;

// Then later...
forEach.call(node.childNodes, function(child) {
    // Do something with `child`
});

Use a simple for loop

Obviously, a simple for loop applies to array-like objects.

for-in

for-in with the same safeguards as with an array should work with array-like objects as well; the caveat for host-provided objects on #1 above may apply.

for-of

for-of will use the iterator provided by the object (if any); we'll have to see how this plays with the various array-like objects, particularly host-provided ones.

Other times, you may want to convert an array-like object into a true array. Doing that is surprisingly easy:

Use the slice method of arrays

We can use the slice method of arrays, which like the other methods mentioned above is "intentionally generic" and so can be used with array-like objects, like this:

var trueArray = Array.prototype.slice.call(arrayLikeObject);
var divs = Array.prototype.slice.call(document.querySelectorAll("div"));

See the Caveat for host-provided objects below. In particular, note that this will fail in IE8 and earlier, which don't let you use host-provided objects as this like that.

...

It's also possible to use ES2015's spread notation (MDN currently calls it an operator; it isn't one), with JavaScript engines that support this feature:

var trueArray = [...iterableObject];

So for instance, if we want to convert a NodeList into a true array, with spread syntax this becomes quite succinct:

var divs = [...document.querySelectorAll("div")];
Array.from

Array.from (ES2015, but shimmable) creates an array from an array-like object, optionally passing the entries through a mapping function first. So:

var divs = Array.from(document.querySelectorAll("div"));

Or if you wanted to get an array of the tag names of the elements with a given class, you'd use the mapping function:

// Arrow function (ES2015):
var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName);

// Standard function (since `Array.from` can be shimmed):
var divs = Array.from(document.querySelectorAll(".some-class"), function(element) {
    return element.tagName;
});

If you use Array.prototype functions with host-provided array-like objects (DOM lists and other things provided by the browser rather than the JavaScript engine), you need to be sure to test in your target environments to make sure the host-provided object behaves properly. Most do behave properly (now), but it's important to test. The reason is that most of the Array.prototype methods you're likely to want to use rely on the host-provided object giving an honest answer to the abstract [[HasProperty]] operation. As of this writing, browsers do a very good job of this, but the ES5 spec did allow for the possibility a host-provided object may not be honest; it's in 8.6.2 (several paragraphs below the big table near the beginning of that section), where it says:

Host objects may implement these internal methods in any manner unless specified otherwise; for example, one possibility is that [[Get]] and [[Put]] for a particular host object indeed fetch and store property values but [[HasProperty]] always generates false.

(I couldn't find the equivalent verbiage in the ES2015 spec, but it's bound to still be the case.) Again, as of this writing the common host-provided array-like objects in modern browsers (NodeList instances, for instance) do handle [[HasProperty]] correctly, but it's important to test.

I would also like to add that .forEach cannot be broken efficiently. You have to throw an exception to perform the break.

@Pius: If you want to break the loop, you can use some. (I would have preferred allowing breaking forEach as well, but they, um, didn't ask me. ;-) )

@T.J.Crowder True, even though it looks more like a work-around as it's not its primary purpose.

@user889030: You need a , after k=0, not a ;. Remember, programming is many things, one of which is close attention to detail... :-)

@JimB: That's covered above (and length isn't a method). :-)

For-each over an array in JavaScript? - Stack Overflow

javascript arrays loops foreach iteration
Rectangle 27 5476

2. Use a simple for loop

  • Don't use for-in unless you use it with safeguards or are at least aware of why it might bite you.
  • a for-of loop (ES2015+ only),
  • Array#forEach (spec | MDN) (or its relatives some and such) (ES5+ only),
  • a simple old-fashioned for loop,
  • or for-in with safeguards.

JavaScript has powerful semantics for looping through arrays and array-like objects. I've split the answer into two parts: Options for genuine arrays, and options for things that are just array-like, such as the arguments object, other iterable objects (ES2015+), DOM collections, and so on.

I'll quickly note that you can use the ES2015 options now, even on ES5 engines, by transpiling ES2015 to ES5. Search for "ES2015 transpiling" / "ES6 transpiling" for more...

You have three options in ECMAScript5 ("ES5"), the version most broadly supported at the moment, and will soon have two more in ECMAScript2015 ("ES2015", "ES6"), the latest version of JavaScript that vendors are working on supporting:

  • Use a simple for loop

If you're using an environment that supports the Array features of ES5 (directly or using a shim), you can use the new forEach (spec | MDN):

var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});

forEach accepts an iterator function and, optionally, a value to use as this when calling that iterator function (not used above). The iterator function is called for each entry in the array, in order, skipping non-existent entries in sparse arrays. Although I only used one argument above, the iterator function is called with three: The value of each entry, the index of that entry, and a reference to the array you're iterating over (in case your function doesn't already have it handy).

Unless you're supporting obsolete browsers like IE8 (which NetApps shows at just over 4% market share as of this writing in September2016), you can happily use forEach in a general-purpose web page without a shim. If you do need to support obsolete browsers, shimming/polyfilling forEach is easily done (search for "es5 shim" for several options).

forEach has the benefit that you don't have to declare indexing and value variables in the containing scope, as they're supplied as arguments to the iteration function, and so nicely scoped to just that iteration.

If you're worried about the runtime cost of making a function call for each array entry, don't be; details.

Additionally, forEach is the "loop through them all" function, but ES5 defined several other useful "work your way through the array and do things" functions, including:

  • every (stops looping the first time the iterator returns false or something falsey)
  • some (stops looping the first time the iterator returns true or something truthy)
  • filter (creates a new array including elements where the filter function returns true and omitting the ones where it returns false)
  • map (creates a new array from the values returned by the iterator function)
  • reduce (builds up a value by repeated calling the iterator, passing in previous values; see the spec for the details; useful for summing the contents of an array and many other things)
reduceRight
reduce

Sometimes the old ways are the best:

If the length of the array won't change during the loop, and it's in performance-sensitive code (unlikely), a slightly more complicated version grabbing the length up front might be a tiny bit faster:

var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}
var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}

But with modern JavaScript engines, it's rare you need to eke out that last bit of juice.

In ES2015 and higher, you can make your index and value variables local to the for loop:

let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
}
//console.log(index); // Would cause "ReferenceError: index is not defined"
//console.log(value); // Would cause "ReferenceError: value is not defined"

And when you do that, not just value but also index is recreated for each loop iteration, meaning closures created in the loop body keep a reference to the index (and value) created for that specific iteration:

let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        alert("Index is: " + index);
    });
}

If you had five divs, you'd get "Index is: 0" if you clicked the first and "Index is: 4" if you clicked the last. This does not work if you use var instead of let.

You'll get people telling you to use for-in, but that's not what for-in is for. for-in loops through the enumerable properties of an object, not the indexes of an array. The order is not guaranteed, not even in ES2015 (ES6). ES2015 does define an order to object properties (via [[OwnPropertyKeys]], [[Enumerate]], and things that use them like Object.getOwnPropertyKeys), but it does not define that for-in will follow that order. (Details in this other answer.)

Still, it can be useful, particularly for sparse arrays, if you use appropriate safeguards:

// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These are explained
        /^0$|^[1-9]\d*$/.test(key) &&    // and then hidden
        key <= 4294967294                // away below
        ) {
        console.log(a[key]);
    }
}

Note the two checks:

That's a tiny bit of added overhead per loop iteration on most arrays, but if you have a sparse array, it can be a more efficient way to loop because it only loops for entries that actually exist. E.g., for the array above, we loop a total of three times (for keys "0", "10", and "10000" remember, they're strings), not 10,001 times.

Now, you won't want to write that every time, so you might put this in your toolkit:

function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) && /^0$|^[1-9]\d*$/.test(prop) && prop <= 4294967294; // 2^32 - 2
}
for (key in a) {
    if (arrayHasOwnIndex(a, key)) {
        console.log(a[key]);
    }
}

Or if you're interested in just a "good enough for most cases" test, you could use this, but while it's close, it's not quite correct:

for (key in a) {
    // "Good enough" for most cases
    if (String(parseInt(key, 10)) === key && a.hasOwnProperty(key)) {
        console.log(a[key]);
    }
}

ES2015 adds iterators to JavaScript. The easiest way to use iterators is the new for-of statement. It looks like this:

var val;
var a = ["a", "b", "c"];
for (val of a) {
    console.log(val);
}

Under the covers, that gets an iterator from the array and loops through it, getting the values from it. This doesn't have the issue that using for-in has, because it uses an iterator defined by the object (the array), and arrays define that their iterators iterate through their entries (not their properties). Unlike for-in in ES5, the order in which the entries are visited is the numeric order of their indexes.

Sometimes, you might want to use an iterator explicitly. You can do that, too, although it's a lot clunkier than for-of. It looks like this:

var a = ["a", "b", "c"];
var it = a.values();
var entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}

The iterator is a function (specifically, a generator) that returns a new object each time you call next. The object returned by the iterator has a property, done, telling us whether it's done, and a property value with the value for that iteration.

The meaning of value varies depending on the iterator; arrays support (at least) three functions that return iterators:

  • values(): This is the one I used above. It returns an iterator where each value is the value for that iteration.
  • keys(): Returns an iterator where each value is the key for that iteration (so for our a above, that would be "0", then "1", then "2").
  • entries(): Returns an iterator where each value is an array in the form [key, value] for that iteration.

(As of this writing, Firefox 29 supports entries and keys but not values.)

Aside from true arrays, there are also array-like objects that have a length property and properties with numeric names: NodeList instances, the arguments object, etc. How do we loop through their contents?

At least some, and possibly most or even all, of the array approaches above frequently apply equally well to array-like objects:

The various functions on Array.prototype are "intentionally generic" and can usually be used on array-like objects via Function#call or Function#apply. (See the Caveat for host-provided objects at the end of this answer, but it's a rare issue.)

forEach
Node
childNodes
Array.prototype.forEach.call(node.childNodes, function(child) {
    // Do something with `child`
});

If you're going to do that a lot, you might want to grab a copy of the function reference into a variable for reuse, e.g.:

// (This is all presumably in some scoping function)
var forEach = Array.prototype.forEach;

// Then later...
forEach.call(node.childNodes, function(child) {
    // Do something with `child`
});

Use a simple for loop

Obviously, a simple for loop applies to array-like objects.

for-in

for-in with the same safeguards as with an array should work with array-like objects as well; the caveat for host-provided objects on #1 above may apply.

for-of

for-of will use the iterator provided by the object (if any); we'll have to see how this plays with the various array-like objects, particularly host-provided ones.

Other times, you may want to convert an array-like object into a true array. Doing that is surprisingly easy:

Use the slice method of arrays

We can use the slice method of arrays, which like the other methods mentioned above is "intentionally generic" and so can be used with array-like objects, like this:

var trueArray = Array.prototype.slice.call(arrayLikeObject);
var divs = Array.prototype.slice.call(document.querySelectorAll("div"));

See the Caveat for host-provided objects below. In particular, note that this will fail in IE8 and earlier, which don't let you use host-provided objects as this like that.

...

It's also possible to use ES2015's spread notation (MDN currently calls it an operator; it isn't one), with JavaScript engines that support this feature:

var trueArray = [...iterableObject];

So for instance, if we want to convert a NodeList into a true array, with spread syntax this becomes quite succinct:

var divs = [...document.querySelectorAll("div")];
Array.from

Array.from (ES2015, but shimmable) creates an array from an array-like object, optionally passing the entries through a mapping function first. So:

var divs = Array.from(document.querySelectorAll("div"));

Or if you wanted to get an array of the tag names of the elements with a given class, you'd use the mapping function:

// Arrow function (ES2015):
var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName);

// Standard function (since `Array.from` can be shimmed):
var divs = Array.from(document.querySelectorAll(".some-class"), function(element) {
    return element.tagName;
});

If you use Array.prototype functions with host-provided array-like objects (DOM lists and other things provided by the browser rather than the JavaScript engine), you need to be sure to test in your target environments to make sure the host-provided object behaves properly. Most do behave properly (now), but it's important to test. The reason is that most of the Array.prototype methods you're likely to want to use rely on the host-provided object giving an honest answer to the abstract [[HasProperty]] operation. As of this writing, browsers do a very good job of this, but the ES5 spec did allow for the possibility a host-provided object may not be honest; it's in 8.6.2 (several paragraphs below the big table near the beginning of that section), where it says:

Host objects may implement these internal methods in any manner unless specified otherwise; for example, one possibility is that [[Get]] and [[Put]] for a particular host object indeed fetch and store property values but [[HasProperty]] always generates false.

(I couldn't find the equivalent verbiage in the ES2015 spec, but it's bound to still be the case.) Again, as of this writing the common host-provided array-like objects in modern browsers (NodeList instances, for instance) do handle [[HasProperty]] correctly, but it's important to test.

I would also like to add that .forEach cannot be broken efficiently. You have to throw an exception to perform the break.

@Pius: If you want to break the loop, you can use some. (I would have preferred allowing breaking forEach as well, but they, um, didn't ask me. ;-) )

@T.J.Crowder True, even though it looks more like a work-around as it's not its primary purpose.

@user889030: You need a , after k=0, not a ;. Remember, programming is many things, one of which is close attention to detail... :-)

@JimB: That's covered above (and length isn't a method). :-)

For-each over an array in JavaScript? - Stack Overflow

javascript arrays loops foreach iteration
Rectangle 27 14

Where to use an ID versus a class

The simple difference between the two is that while a class can be used repeatedly on a page, an ID must only be used once per page. Therefore, it is appropriate to use an ID on the div element that is marking up the main content on the page, as there will only be one main content section. In contrast, you must use a class to set up alternating row colors on a table, as they are by definition going to be used more than once.

IDs are an incredibly powerful tool. An element with an ID can be the target of a piece of JavaScript that manipulates the element or its contents in some way. The ID attribute can be used as the target of an internal link, replacing anchor tags with name attributes. Finally, if you make your IDs clear and logical, they can serve as a sort of self documentation within the document. For example, you do not necessarily need to add a comment before a block stating that a block of code will contain the main content if the opening tag of the block has an ID of, say, "main", "header", "footer", etc.

css - Difference between div id and div class - Stack Overflow

css class html
Rectangle 27 41

My opinion is that 'this' in javascript has enough issues on it's own, and that adding another meaning / use for it not a good idea.

There is now the 'controller as' syntax, discussed here. I am not a fan, but now that it's a more 'official' AngularJS construct it deserves some attention.

I think we first need to understand the new "UserCtrl as uCtrl" syntax before we can say which we think is better.

Re 'UserCtrl as uCtrl', I agree, this needs to be understood. I think it's a bad idea, for most of the same reasons as the arguments made here : groups.google.com/forum/#!topic/angular/84selECbp1I

If you are familiar with oop in JS it makes perfect sense. A controller is a class, and angular uses the new operator each time a controller is created. You are welcome to dislike it, but stating there are issues with using 'this' is misleading. It is an acceptable use case for 'this'.

$scope adds nothing to the clarity. In fact it can be be very difficult to know what is going on in the view when using $scope and you have nested scopes. The controller as syntax along with using this adds much more clarity. In the view it is nice and clear which controller's scope a method or property originates from.

angularjs - Should I use `this` or `$scope`? - Stack Overflow

angularjs
Rectangle 27 41

My opinion is that 'this' in javascript has enough issues on it's own, and that adding another meaning / use for it not a good idea.

There is now the 'controller as' syntax, discussed here. I am not a fan, but now that it's a more 'official' AngularJS construct it deserves some attention.

I think we first need to understand the new "UserCtrl as uCtrl" syntax before we can say which we think is better.

Re 'UserCtrl as uCtrl', I agree, this needs to be understood. I think it's a bad idea, for most of the same reasons as the arguments made here : groups.google.com/forum/#!topic/angular/84selECbp1I

If you are familiar with oop in JS it makes perfect sense. A controller is a class, and angular uses the new operator each time a controller is created. You are welcome to dislike it, but stating there are issues with using 'this' is misleading. It is an acceptable use case for 'this'.

$scope adds nothing to the clarity. In fact it can be be very difficult to know what is going on in the view when using $scope and you have nested scopes. The controller as syntax along with using this adds much more clarity. In the view it is nice and clear which controller's scope a method or property originates from.

angularjs - Should I use `this` or `$scope`? - Stack Overflow

angularjs
Rectangle 27 41

My opinion is that 'this' in javascript has enough issues on it's own, and that adding another meaning / use for it not a good idea.

There is now the 'controller as' syntax, discussed here. I am not a fan, but now that it's a more 'official' AngularJS construct it deserves some attention.

I think we first need to understand the new "UserCtrl as uCtrl" syntax before we can say which we think is better.

Re 'UserCtrl as uCtrl', I agree, this needs to be understood. I think it's a bad idea, for most of the same reasons as the arguments made here : groups.google.com/forum/#!topic/angular/84selECbp1I

If you are familiar with oop in JS it makes perfect sense. A controller is a class, and angular uses the new operator each time a controller is created. You are welcome to dislike it, but stating there are issues with using 'this' is misleading. It is an acceptable use case for 'this'.

$scope adds nothing to the clarity. In fact it can be be very difficult to know what is going on in the view when using $scope and you have nested scopes. The controller as syntax along with using this adds much more clarity. In the view it is nice and clear which controller's scope a method or property originates from.

angularjs - Should I use `this` or `$scope`? - Stack Overflow

angularjs
Rectangle 27 819

TypeScript is a superset of JavaScript which primarily provides optional static typing, classes and interfaces. One of the big benefits is to enable IDEs to provide a richer environment for spotting common errors as you type the code.

To get an idea of what I mean, watch Microsoft's introductory video on the language.

For a large JavaScript project, adopting TypeScript might result in more robust software, while still being deployable where a regular JavaScript application would run.

It is open source, but you only get the clever Intellisense as you type if you use a supported IDE. Initially, this was only Microsoft's Visual Studio (also noted in blog post from Miguel de Icaza). These days, other IDEs offer TypeScript support too.

There's CoffeeScript, but that really serves a different purpose. IMHO, CoffeeScript provides readability for humans, but TypeScript also provides deep readability for tools through its optional static typing (see this recent blog post for a little more critique). There's also Dart but that's a full on replacement for JavaScript (though it can produce JavaScript code)

As an example, here's some TypeScript (you can play with this in the TypeScript Playground)

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

And here's the JavaScript it would produce

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();

Notice how the TypeScript defines the type of member variables and class method parameters. This is removed when translating to JavaScript, but used by the IDE and compiler to spot errors, like passing a numeric type to the constructor.

It's also capable of inferring types which aren't explicitly declared, for example, it would determine the greet() method returns a string.

Many browsers and IDEs offer direct debugging support through sourcemaps. See this Stack Overflow question for more details: Debugging TypeScript code with Visual Studio

@nawfal yes i dont like Atom multiple processes the final 1.0 version isnt released yet and solving memory issue is on their roadmap for 1.0 , lets see !

The problem with these tools is that you never get the full performance out of javascript. Yes, it provides good readability but the compiled code is sometimes very clunky. You rely on a third-party tool to write native javascript, I think this is not the way to go, it's like transforming a language to another language. Wanting to change a language that's not another language to behave like another language you like, that's stupid and silly. ...... (end of part 1)......

@Erwinus: Did you still program with assembler?

@Erwinus The point of TypeScript is to provide compile time type checking. If you don't see the value in that, that's perfectly fine. TypeScript has been refereed to as "your first unit test". There are many resources that discuss whether or not optional type checking has value, and are more detail than what we can do here. I'm not trying to convince you of anything, just correcting a misconception.

What is TypeScript and why would I use it in place of JavaScript? - St...

javascript typescript
Rectangle 27 819

TypeScript is a superset of JavaScript which primarily provides optional static typing, classes and interfaces. One of the big benefits is to enable IDEs to provide a richer environment for spotting common errors as you type the code.

To get an idea of what I mean, watch Microsoft's introductory video on the language.

For a large JavaScript project, adopting TypeScript might result in more robust software, while still being deployable where a regular JavaScript application would run.

It is open source, but you only get the clever Intellisense as you type if you use a supported IDE. Initially, this was only Microsoft's Visual Studio (also noted in blog post from Miguel de Icaza). These days, other IDEs offer TypeScript support too.

There's CoffeeScript, but that really serves a different purpose. IMHO, CoffeeScript provides readability for humans, but TypeScript also provides deep readability for tools through its optional static typing (see this recent blog post for a little more critique). There's also Dart but that's a full on replacement for JavaScript (though it can produce JavaScript code)

As an example, here's some TypeScript (you can play with this in the TypeScript Playground)

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

And here's the JavaScript it would produce

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();

Notice how the TypeScript defines the type of member variables and class method parameters. This is removed when translating to JavaScript, but used by the IDE and compiler to spot errors, like passing a numeric type to the constructor.

It's also capable of inferring types which aren't explicitly declared, for example, it would determine the greet() method returns a string.

Many browsers and IDEs offer direct debugging support through sourcemaps. See this Stack Overflow question for more details: Debugging TypeScript code with Visual Studio

@nawfal yes i dont like Atom multiple processes the final 1.0 version isnt released yet and solving memory issue is on their roadmap for 1.0 , lets see !

The problem with these tools is that you never get the full performance out of javascript. Yes, it provides good readability but the compiled code is sometimes very clunky. You rely on a third-party tool to write native javascript, I think this is not the way to go, it's like transforming a language to another language. Wanting to change a language that's not another language to behave like another language you like, that's stupid and silly. ...... (end of part 1)......

@Erwinus: Did you still program with assembler?

@Erwinus The point of TypeScript is to provide compile time type checking. If you don't see the value in that, that's perfectly fine. TypeScript has been refereed to as "your first unit test". There are many resources that discuss whether or not optional type checking has value, and are more detail than what we can do here. I'm not trying to convince you of anything, just correcting a misconception.

What is TypeScript and why would I use it in place of JavaScript? - St...

javascript typescript
Rectangle 27 548

Though the accepted answer is fine, I felt it really doesn't do TypeScript justice at this point. It is not the early days anymore. TypeScript is finding a lot more adoption now with several popular frameworks being written in TypeScript. The reasons why you should choose TypeScript instead of JavaScript are many now.

JavaScript is standardized through the ECMAScript standards. Not all browsers in use support all features of newer ECMAScript standards (see this table). TypeScript supports new ECMAScript standards and compiles them to (older) ECMAScript targets of your choosing (current targets are 3, 5 and 6 [a.k.a. 2015]). This means that you can use features of ES2015 and beyond, like modules, lambda functions, classes, the spread operator, destructuring, today. It also adds type support of course, which is not part of any ECMAScript standard and may likely never be due to the interpreted nature instead of compiled nature of JavaScript. The type system of TypeScript is relatively rich and includes: interfaces, enums, hybrid types, generics, union and intersection types, access modifiers and much more. The official website of TypeScript gives an overview of these features.

TypeScript has a unique philosophy compared to other languages that compile to JavaScript. JavaScript code is valid TypeScript code; TypeScript is a superset of JavaScript. You can almost rename your .js files to .ts files and start using TypeScript. TypeScript files are compiled to readable JavaScript, so that migration back is possible and understanding the compiled TypeScript is not hard at all. This way TypeScript builds on the successes of JavaScript while improving on its weaknesses.

On the one hand, you have future proof tools that take modern ECMAScript standards and compile it down to older JavaScript versions with Babel being the most popular one. On the other hand, you have languages that may totally differ from JavaScript which target JavaScript, like Coffeescript, Clojure, Dart, Elm, Haxe, ScalaJs, and a whole host more (see this list). These languages, though they might be better than where JavaScript's future might ever lead, run a greater risk of not finding enough adoption for their futures to be guaranteed. You might also have more trouble finding experienced developers for some of these languages, though the ones you will find can often be more enthusiastic. Interop with JavaScript can also be a bit more involved, since they are farther removed from what JavaScript actually is.

TypeScript sits in between these two extremes, thus balancing the risk. TypeScript is not a risky choice by any standard. It takes very little effort to get used to if you are known to JavaScript, since it is not a completely different language, has excellent JavaScript interoperability support and it has seen a lot of adoption recently.

JavaScript is dynamically typed. This means JavaScript does not know what type a variable is until it is actually instantiated at run-time. This also means that it may be too late. TypeScript adds type support to JavaScript. Bugs that are caused by false assumptions of some variable being of a certain type can be completely eradicated if you play your cards right; how strict you type your code or if you type your code at all is up to you.

TypeScript makes typing a bit easier and a lot less explicit by the usage of type inference. For example: var x = "hello" in TypeScript is the same as var x : string = "hello". The type is simply inferred from its use. Even it you don't explicitly type the types, they are still there to save you from doing something which otherwise would result in a run-time error.

TypeScript is optionally typed by default. For example function divideByTwo(x) { return x / 2 } is a valid function in TypeScript which can be called with any kind of parameter, even though calling it with a string will obviously result in a runtime error. Just like you are used to in JavaScript. This works, because when no type was explicitly assigned and the type could not be inferred, like in the divideByTwo example, TypeScript will implicitly assign the type any. This means the divideByTwo function's type signature automatically becomes function divideByTwo(x : any) : any. There is a compiler flag to disallow this behavior: --noImplicitAny. Enabling this flag gives you a greater degree of safety, but also means you will have to do more typing.

It is interesting to note that this very same paper finds that TypeScript is less error prone then JavaScript:

For those with positive coefficients we can expect that the language is associated with, ceteris paribus, a greater number of defect fixes. These languages include C, C++, JavaScript, Objective-C, Php, and Python. The languages Clojure, Haskell, Ruby, Scala, and TypeScript, all have negative coefficients implying that these languages are less likely than the average to result in defect fixing commits.

The development experience with TypeScript is a great improvement over JavaScript. The IDE is informed in real-time by the TypeScript compiler on its rich type information. This gives a couple of major advantages. For example, with TypeScript you can safely do refactorings like renames across your entire codebase. Through code completion you can get inline help on whatever functions a library might offer. No more need to remember them or look them up in online references. Compilation errors are reported directly in the IDE with a red squiggly line while you are busy coding. All in all this allows for a significant gain in productivity compared to working with JavaScript. One can spend more time coding and less time debugging.

There is a wide range of IDEs that have excellent support for TypeScript, like Visual Studio & VS code, Atom, Sublime, and IntelliJ/WebStorm.

Runtime errors of the form cannot read property 'x' of undefined or undefined is not a function are very commonly caused by bugs in JavaScript code. Out of the box TypeScript already reduces the probability of these kinds of errors occurring, since one cannot use a variable that is not known to the TypeScript compiler (with the exception of properties of any typed variables). It is still possible though to mistakenly utilize a variable that is set to undefined. However, with the 2.0 version of TypeScript you can eliminate these kinds of errors all together through the usage of non-nullable types. This works as follows:

With strict null checks enabled (--strictNullChecks compiler flag) the TypeScript compiler will not allow undefined to be assigned to a variable unless you explicitly declare it to be of nullable type. For example, let x : number = undefined will result in a compile error. This fits perfectly with type theory, since undefined is not a number. One can define x to be a sum type of number and undefined to correct this: let x : number | undefined = undefined. The short hand notation is let x : number? = undefined.

Once a type is known to be nullable, meaning it is of a type that can also be of the value null or undefined, the TypeScript compiler can determine through control flow based type analysis whether or not your code can safely use a variable or not. In other words when you check a variable is undefined through for example an if statement the TypeScript compiler will infer that the type in that branch of your code's control flow is not anymore nullable and therefore can safely be used. Here is a simple example:

let x : number?;
if (x !== undefined) x += 1; // this line will compile, because x is checked.
x += 1; // this line will fail compilation, because x might be undefined.

During the build 2016 conference co-designer of TypeScript Anders Hejlsberg gave a detailed explanation and demonstration of this feature: video (from 44:30 to 56:30).

To use TypeScript you need a build process to compile to JavaScript code. The build process generally takes only a couple of seconds depending of course on the size of your project. The TypeScript compiler supports incremental compilation (--watch compiler flag), so that all subsequent changes can be compiled at greater speed.

The TypeScript compiler can inline source map information in the generated .js files or create separate .map files. Source map information can be used by debugging utilities like the Chrome DevTools and other IDE's to relate the lines in the JavaScript to the ones that generated them in the TypeScript. This makes it possible for you to set breakpoints and inspect variables during runtime directly on your TypeScript code. Source map information works pretty good, it was around long before TypeScript, but debugging TypeScript is generally not as great as when using JavaScript directly. Take the this keyword for example. Due to the changed semantics of the this keyword around closures since ES2015, this may actually exists during runtime as a variable called _this (see this answer). This may confuse you during debugging, but generally is not a problem if you know about it or inspect the JavaScript code. It should be noted that Babel suffers the exact same kind of issue.

There are a few other tricks the TypeScript compiler can do, like generating intercepting code based on decorators, generating module loading code for different module systems and parsing JSX. However, you will likely require a build tool besides the Typescript compiler. For example if you want to compress your code you will have to add other tools to your build process to do so.

There are TypeScript compilation plugins available for Webpack, Gulp, Grunt and pretty much any other JavaScript build tool out there. The TypeScript documentation has a section on integrating with build tools covering them all. A linter is also available in case you would like even more build time checking. There are also a great number of seed projects out there that will get you started with TypeScript in combination with a bunch of other technologies like Angular 2, React, Ember, SystemJs, WebPack, Gulp, etc.

Since TypeScript is so closely related to JavaScript it has great interoperability capabilities, but some extra work is required to work with JavaScript libraries in TypeScript. TypeScript definitions are needed so that the TypeScript compiler understands that function calls like _.groupBy or angular.copy or $.fadeOut are not in fact illegal statements. The definitions for these functions are placed in .d.ts files.

The simplest form a definition can take is to allow an identifier to be used in any way. For example, when using Lodash, a single line definition file declare var _ : any will allow you to call any function you want on _, but then of course you are also still able to make mistakes: _.foobar() would be a legal TypeScript call, but is of course an illegal call at run-time. If you want proper type support and code completion your definition file needs to to be more exact (see lodash definitions for an example).

Npm modules that come pre-packaged with their own type definitions are automatically understood by the TypeScript compiler (see documentation). For pretty much any other semi-popular JavaScript library that does not include its own definitions (most projects at this point) somebody out there has already made a .d.ts file. These can be downloaded and managed with a command line tool called Typings. Typings gets most of its type definitions from a Github repository called DefinitelyTyped, but is also able to get them via other source like Github, Npm, Bower, etc. After installing Typings you can run typings install lodash on the command-line in your project directory and you will be ready to start using Lodash. Now your IDE will tell you exactly which Lodash functions are available when you type _. in your editor.

There is one caveat: the TypeScript definitions must match the version of the library you are using at runtime. If they do not, TypeScript might disallow you from calling a function or dereferencing a variable that exist or allow you to call a function or dereference a variable that does not exist. Typings uses a registry to be able to provide different versions of definitions. This is a fairly recent development and to be honest there are not a lot of different versions of libraries available yet, so often times times it is simply the best to use the latest version of a library as definitions tend to be up to date.

To be honest, there is a slight hassle to this and it may be one of the reasons you do not choose TypeScript, but instead go for something like Babel that does not suffer from having to get type definitions at all. On the other hand, if you know what you are doing you can easily overcome any kind of issues caused by incorrect or missing definition files.

Any .js file can be renamed to a .ts and ran through the TypeScript compiler to get syntactically the same JavaScript code as an output (if it was syntactically correct in the first place). Even when the TypeScript compiler gets compilation errors it will still produce a .js file. It can even accept .js files as input with the --allowJs flag. This allows you to start with TypeScript right away. Unfortunately compilation errors are likely to occur in the beginning. One does need to remember that these are not show-stopping errors like you may be used to with other compilers.

The compilation errors one gets in the beginning when converting a JavaScript project to a TypeScript project are unavoidable by TypeScript's nature. TypeScript checks all code for validity and thus it needs to know about all functions and variables that are used. Thus type definitions need to be in place for all of them otherwise compilation errors are bound to occur. As mentioned in the chapter above, for pretty much any JavaScript framework there are .d.ts files that can easily be acquired with a few typings install commands. It might however be that you've used some obscure library for which no TypeScript definitions are available or that you've polyfilled some JavaScript primitives. In that case you must supply type definitions for these bits in order for the compilation errors to dissapear. Just create a .d.ts file and include it in the tsconfig.json's files array, so that it is always considered by the TypeScript compiler. In it declare those bits that TypeScript does not know about as type any. Once you've eliminated all errors you can gradually introduce typing to those parts according to your needs.

Some work on (re)configuring your build pipeline will also be needed to get TypeScript into the build pipeline. As mentioned in the chapter on compilation there are plenty of good resources out there and I encourage you to look for seed projects that use the combination of tools you want to be working with.

The biggest hurdle is the learning curve. I encourage you to play around with a small project at first. Look how it works, how it builds, which files it uses, how it is configured, how it functions in your IDE, how it is structured, which tools it uses, etc. Converting a large JavaScript codebase to TypeScript is very doable when you know what you are doing, but it might be frustrating when you don't.

TypeScript is open source (Apache 2 licensed, see github) and backed by Microsoft. Anders Hejlsberg, the lead architect of C# is spearheading the project. It's a very active project; the TypeScript team has been releasing a lot of new features in the last few years and a lot of great ones are still planned to come (see the roadmap). It also is currently trending (see google trends). Npm downloads have increased 20 fold since last year. In February 2016 TypeScript had over a million downloads per month (source). Many great projects are coded nowadays using TypeScript, most notably Angular 2 and RxJs.

My only gripe with TS is its spartan error reporting, comparing to FB flowtype

"JavaScript code is valid TypeScript code" - this is actually not always true. I mean code like if(1 === '1') {} gives you an error in TS and in JS don't. But most of the time, if JS code is well-written it's true.

If you have lost your precious productive time fretting over a missing semi colon, writing in Typescript would be a life saver.

let x : number? = undefined is a syntax error. You can use the ? for optional parameters and properties but not for variables. Also the '?' goes after the parameter or property name, not the type.

What is TypeScript and why would I use it in place of JavaScript? - St...

javascript typescript
Rectangle 27 546

Though the accepted answer is fine, I felt it really doesn't do TypeScript justice at this point. It is not the early days anymore. TypeScript is finding a lot more adoption now with several popular frameworks being written in TypeScript. The reasons why you should choose TypeScript instead of JavaScript are many now.

JavaScript is standardized through the ECMAScript standards. Not all browsers in use support all features of newer ECMAScript standards (see this table). TypeScript supports new ECMAScript standards and compiles them to (older) ECMAScript targets of your choosing (current targets are 3, 5 and 6 [a.k.a. 2015]). This means that you can use features of ES2015 and beyond, like modules, lambda functions, classes, the spread operator, destructuring, today. It also adds type support of course, which is not part of any ECMAScript standard and may likely never be due to the interpreted nature instead of compiled nature of JavaScript. The type system of TypeScript is relatively rich and includes: interfaces, enums, hybrid types, generics, union and intersection types, access modifiers and much more. The official website of TypeScript gives an overview of these features.

TypeScript has a unique philosophy compared to other languages that compile to JavaScript. JavaScript code is valid TypeScript code; TypeScript is a superset of JavaScript. You can almost rename your .js files to .ts files and start using TypeScript. TypeScript files are compiled to readable JavaScript, so that migration back is possible and understanding the compiled TypeScript is not hard at all. This way TypeScript builds on the successes of JavaScript while improving on its weaknesses.

On the one hand, you have future proof tools that take modern ECMAScript standards and compile it down to older JavaScript versions with Babel being the most popular one. On the other hand, you have languages that may totally differ from JavaScript which target JavaScript, like Coffeescript, Clojure, Dart, Elm, Haxe, ScalaJs, and a whole host more (see this list). These languages, though they might be better than where JavaScript's future might ever lead, run a greater risk of not finding enough adoption for their futures to be guaranteed. You might also have more trouble finding experienced developers for some of these languages, though the ones you will find can often be more enthusiastic. Interop with JavaScript can also be a bit more involved, since they are farther removed from what JavaScript actually is.

TypeScript sits in between these two extremes, thus balancing the risk. TypeScript is not a risky choice by any standard. It takes very little effort to get used to if you are known to JavaScript, since it is not a completely different language, has excellent JavaScript interoperability support and it has seen a lot of adoption recently.

JavaScript is dynamically typed. This means JavaScript does not know what type a variable is until it is actually instantiated at run-time. This also means that it may be too late. TypeScript adds type support to JavaScript. Bugs that are caused by false assumptions of some variable being of a certain type can be completely eradicated if you play your cards right; how strict you type your code or if you type your code at all is up to you.

TypeScript makes typing a bit easier and a lot less explicit by the usage of type inference. For example: var x = "hello" in TypeScript is the same as var x : string = "hello". The type is simply inferred from its use. Even it you don't explicitly type the types, they are still there to save you from doing something which otherwise would result in a run-time error.

TypeScript is optionally typed by default. For example function divideByTwo(x) { return x / 2 } is a valid function in TypeScript which can be called with any kind of parameter, even though calling it with a string will obviously result in a runtime error. Just like you are used to in JavaScript. This works, because when no type was explicitly assigned and the type could not be inferred, like in the divideByTwo example, TypeScript will implicitly assign the type any. This means the divideByTwo function's type signature automatically becomes function divideByTwo(x : any) : any. There is a compiler flag to disallow this behavior: --noImplicitAny. Enabling this flag gives you a greater degree of safety, but also means you will have to do more typing.

It is interesting to note that this very same paper finds that TypeScript is less error prone then JavaScript:

For those with positive coefficients we can expect that the language is associated with, ceteris paribus, a greater number of defect fixes. These languages include C, C++, JavaScript, Objective-C, Php, and Python. The languages Clojure, Haskell, Ruby, Scala, and TypeScript, all have negative coefficients implying that these languages are less likely than the average to result in defect fixing commits.

The development experience with TypeScript is a great improvement over JavaScript. The IDE is informed in real-time by the TypeScript compiler on its rich type information. This gives a couple of major advantages. For example, with TypeScript you can safely do refactorings like renames across your entire codebase. Through code completion you can get inline help on whatever functions a library might offer. No more need to remember them or look them up in online references. Compilation errors are reported directly in the IDE with a red squiggly line while you are busy coding. All in all this allows for a significant gain in productivity compared to working with JavaScript. One can spend more time coding and less time debugging.

There is a wide range of IDEs that have excellent support for TypeScript, like Visual Studio & VS code, Atom, Sublime, and IntelliJ/WebStorm.

Runtime errors of the form cannot read property 'x' of undefined or undefined is not a function are very commonly caused by bugs in JavaScript code. Out of the box TypeScript already reduces the probability of these kinds of errors occurring, since one cannot use a variable that is not known to the TypeScript compiler (with the exception of properties of any typed variables). It is still possible though to mistakenly utilize a variable that is set to undefined. However, with the 2.0 version of TypeScript you can eliminate these kinds of errors all together through the usage of non-nullable types. This works as follows:

With strict null checks enabled (--strictNullChecks compiler flag) the TypeScript compiler will not allow undefined to be assigned to a variable unless you explicitly declare it to be of nullable type. For example, let x : number = undefined will result in a compile error. This fits perfectly with type theory, since undefined is not a number. One can define x to be a sum type of number and undefined to correct this: let x : number | undefined = undefined. The short hand notation is let x : number? = undefined.

Once a type is known to be nullable, meaning it is of a type that can also be of the value null or undefined, the TypeScript compiler can determine through control flow based type analysis whether or not your code can safely use a variable or not. In other words when you check a variable is undefined through for example an if statement the TypeScript compiler will infer that the type in that branch of your code's control flow is not anymore nullable and therefore can safely be used. Here is a simple example:

let x : number?;
if (x !== undefined) x += 1; // this line will compile, because x is checked.
x += 1; // this line will fail compilation, because x might be undefined.

During the build 2016 conference co-designer of TypeScript Anders Hejlsberg gave a detailed explanation and demonstration of this feature: video (from 44:30 to 56:30).

To use TypeScript you need a build process to compile to JavaScript code. The build process generally takes only a couple of seconds depending of course on the size of your project. The TypeScript compiler supports incremental compilation (--watch compiler flag), so that all subsequent changes can be compiled at greater speed.

The TypeScript compiler can inline source map information in the generated .js files or create separate .map files. Source map information can be used by debugging utilities like the Chrome DevTools and other IDE's to relate the lines in the JavaScript to the ones that generated them in the TypeScript. This makes it possible for you to set breakpoints and inspect variables during runtime directly on your TypeScript code. Source map information works pretty good, it was around long before TypeScript, but debugging TypeScript is generally not as great as when using JavaScript directly. Take the this keyword for example. Due to the changed semantics of the this keyword around closures since ES2015, this may actually exists during runtime as a variable called _this (see this answer). This may confuse you during debugging, but generally is not a problem if you know about it or inspect the JavaScript code. It should be noted that Babel suffers the exact same kind of issue.

There are a few other tricks the TypeScript compiler can do, like generating intercepting code based on decorators, generating module loading code for different module systems and parsing JSX. However, you will likely require a build tool besides the Typescript compiler. For example if you want to compress your code you will have to add other tools to your build process to do so.

There are TypeScript compilation plugins available for Webpack, Gulp, Grunt and pretty much any other JavaScript build tool out there. The TypeScript documentation has a section on integrating with build tools covering them all. A linter is also available in case you would like even more build time checking. There are also a great number of seed projects out there that will get you started with TypeScript in combination with a bunch of other technologies like Angular 2, React, Ember, SystemJs, WebPack, Gulp, etc.

Since TypeScript is so closely related to JavaScript it has great interoperability capabilities, but some extra work is required to work with JavaScript libraries in TypeScript. TypeScript definitions are needed so that the TypeScript compiler understands that function calls like _.groupBy or angular.copy or $.fadeOut are not in fact illegal statements. The definitions for these functions are placed in .d.ts files.

The simplest form a definition can take is to allow an identifier to be used in any way. For example, when using Lodash, a single line definition file declare var _ : any will allow you to call any function you want on _, but then of course you are also still able to make mistakes: _.foobar() would be a legal TypeScript call, but is of course an illegal call at run-time. If you want proper type support and code completion your definition file needs to to be more exact (see lodash definitions for an example).

Npm modules that come pre-packaged with their own type definitions are automatically understood by the TypeScript compiler (see documentation). For pretty much any other semi-popular JavaScript library that does not include its own definitions (most projects at this point) somebody out there has already made a .d.ts file. These can be downloaded and managed with a command line tool called Typings. Typings gets most of its type definitions from a Github repository called DefinitelyTyped, but is also able to get them via other source like Github, Npm, Bower, etc. After installing Typings you can run typings install lodash on the command-line in your project directory and you will be ready to start using Lodash. Now your IDE will tell you exactly which Lodash functions are available when you type _. in your editor.

There is one caveat: the TypeScript definitions must match the version of the library you are using at runtime. If they do not, TypeScript might disallow you from calling a function or dereferencing a variable that exist or allow you to call a function or dereference a variable that does not exist. Typings uses a registry to be able to provide different versions of definitions. This is a fairly recent development and to be honest there are not a lot of different versions of libraries available yet, so often times times it is simply the best to use the latest version of a library as definitions tend to be up to date.

To be honest, there is a slight hassle to this and it may be one of the reasons you do not choose TypeScript, but instead go for something like Babel that does not suffer from having to get type definitions at all. On the other hand, if you know what you are doing you can easily overcome any kind of issues caused by incorrect or missing definition files.

Any .js file can be renamed to a .ts and ran through the TypeScript compiler to get syntactically the same JavaScript code as an output (if it was syntactically correct in the first place). Even when the TypeScript compiler gets compilation errors it will still produce a .js file. It can even accept .js files as input with the --allowJs flag. This allows you to start with TypeScript right away. Unfortunately compilation errors are likely to occur in the beginning. One does need to remember that these are not show-stopping errors like you may be used to with other compilers.

The compilation errors one gets in the beginning when converting a JavaScript project to a TypeScript project are unavoidable by TypeScript's nature. TypeScript checks all code for validity and thus it needs to know about all functions and variables that are used. Thus type definitions need to be in place for all of them otherwise compilation errors are bound to occur. As mentioned in the chapter above, for pretty much any JavaScript framework there are .d.ts files that can easily be acquired with a few typings install commands. It might however be that you've used some obscure library for which no TypeScript definitions are available or that you've polyfilled some JavaScript primitives. In that case you must supply type definitions for these bits in order for the compilation errors to dissapear. Just create a .d.ts file and include it in the tsconfig.json's files array, so that it is always considered by the TypeScript compiler. In it declare those bits that TypeScript does not know about as type any. Once you've eliminated all errors you can gradually introduce typing to those parts according to your needs.

Some work on (re)configuring your build pipeline will also be needed to get TypeScript into the build pipeline. As mentioned in the chapter on compilation there are plenty of good resources out there and I encourage you to look for seed projects that use the combination of tools you want to be working with.

The biggest hurdle is the learning curve. I encourage you to play around with a small project at first. Look how it works, how it builds, which files it uses, how it is configured, how it functions in your IDE, how it is structured, which tools it uses, etc. Converting a large JavaScript codebase to TypeScript is very doable when you know what you are doing, but it might be frustrating when you don't.

TypeScript is open source (Apache 2 licensed, see github) and backed by Microsoft. Anders Hejlsberg, the lead architect of C# is spearheading the project. It's a very active project; the TypeScript team has been releasing a lot of new features in the last few years and a lot of great ones are still planned to come (see the roadmap). It also is currently trending (see google trends). Npm downloads have increased 20 fold since last year. In February 2016 TypeScript had over a million downloads per month (source). Many great projects are coded nowadays using TypeScript, most notably Angular 2 and RxJs.

My only gripe with TS is its spartan error reporting, comparing to FB flowtype

"JavaScript code is valid TypeScript code" - this is actually not always true. I mean code like if(1 === '1') {} gives you an error in TS and in JS don't. But most of the time, if JS code is well-written it's true.

If you have lost your precious productive time fretting over a missing semi colon, writing in Typescript would be a life saver.

let x : number? = undefined is a syntax error. You can use the ? for optional parameters and properties but not for variables. Also the '?' goes after the parameter or property name, not the type.

What is TypeScript and why would I use it in place of JavaScript? - St...

javascript typescript
Rectangle 27 64

Custom Tooltips with pure CSS - no JavaScript needed:

As an alternative to the default title attribute tooltips, you can make your own custom CSS tooltips using :before/:after pseudo elements and HTML5 data-* attributes.

Using the provided CSS, you can add a tooltip to an element using the data-tooltip attribute.

You can also control the position of the custom tooltip using the data-tooltip-position attribute (accepted values: top/right/bottom/left).

For instance, the following will add a tooltop positioned at the bottom of the span element.

<span data-tooltip="Custom tooltip text." data-tooltip-position="bottom">Custom bottom tooltip.</span>

You can display the custom tooltips with pseudo elements by retrieving the custom attribute values using the attr() function.

[data-tooltip]:before {
    content: attr(data-tooltip);
}

In terms of positioning the tooltip, just use the attribute selector and change the placement based on the attribute's value.

Full CSS used in the example

[data-tooltip] {
    display: inline-block;
    position: relative;
    cursor: help;
    padding: 4px;
}
/* Tooltip styling */
[data-tooltip]:before {
    content: attr(data-tooltip);
    display: none;
    position: absolute;
    background: #000;
    color: #fff;
    padding: 4px 8px;
    font-size: 14px;
    line-height: 1.4;
    min-width: 100px;
    text-align: center;
    border-radius: 4px;
}
/* Dynamic horizontal centering */
[data-tooltip-position="top"]:before,
[data-tooltip-position="bottom"]:before {
    left: 50%;
    -ms-transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    -webkit-transform: translateX(-50%);
    transform: translateX(-50%);
}
/* Dynamic vertical centering */
[data-tooltip-position="right"]:before,
[data-tooltip-position="left"]:before {
    top: 50%;
    -ms-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    transform: translateY(-50%);
}
[data-tooltip-position="top"]:before {
    bottom: 100%;
    margin-bottom: 6px;
}
[data-tooltip-position="right"]:before {
    left: 100%;
    margin-left: 6px;
}
[data-tooltip-position="bottom"]:before {
    top: 100%;
    margin-top: 6px;
}
[data-tooltip-position="left"]:before {
    right: 100%;
    margin-right: 6px;
}

/* Tooltip arrow styling/placement */
[data-tooltip]:after {
    content: '';
    display: none;
    position: absolute;
    width: 0;
    height: 0;
    border-color: transparent;
    border-style: solid;
}
/* Dynamic horizontal centering for the tooltip */
[data-tooltip-position="top"]:after,
[data-tooltip-position="bottom"]:after {
    left: 50%;
    margin-left: -6px;
}
/* Dynamic vertical centering for the tooltip */
[data-tooltip-position="right"]:after,
[data-tooltip-position="left"]:after {
    top: 50%;
    margin-top: -6px;
}
[data-tooltip-position="top"]:after {
    bottom: 100%;
    border-width: 6px 6px 0;
    border-top-color: #000;
}
[data-tooltip-position="right"]:after {
    left: 100%;
    border-width: 6px 6px 6px 0;
    border-right-color: #000;
}
[data-tooltip-position="bottom"]:after {
    top: 100%;
    border-width: 0 6px 6px;
    border-bottom-color: #000;
}
[data-tooltip-position="left"]:after {
    right: 100%;
    border-width: 6px 0 6px 6px;
    border-left-color: #000;
}
/* Show the tooltip when hovering */
[data-tooltip]:hover:before,
[data-tooltip]:hover:after {
    display: block;
    z-index: 50;
}

This was great except doesn't work in IE10 :/

Yes I just tested it and also wasn't surprised it didn't work .Good old IE! ;)

@JoshCrozier it helped a lot

html - How do I add a tool tip to a span element? - Stack Overflow

html css
Rectangle 27 64

Custom Tooltips with pure CSS - no JavaScript needed:

As an alternative to the default title attribute tooltips, you can make your own custom CSS tooltips using :before/:after pseudo elements and HTML5 data-* attributes.

Using the provided CSS, you can add a tooltip to an element using the data-tooltip attribute.

You can also control the position of the custom tooltip using the data-tooltip-position attribute (accepted values: top/right/bottom/left).

For instance, the following will add a tooltop positioned at the bottom of the span element.

<span data-tooltip="Custom tooltip text." data-tooltip-position="bottom">Custom bottom tooltip.</span>

You can display the custom tooltips with pseudo elements by retrieving the custom attribute values using the attr() function.

[data-tooltip]:before {
    content: attr(data-tooltip);
}

In terms of positioning the tooltip, just use the attribute selector and change the placement based on the attribute's value.

Full CSS used in the example

[data-tooltip] {
    display: inline-block;
    position: relative;
    cursor: help;
    padding: 4px;
}
/* Tooltip styling */
[data-tooltip]:before {
    content: attr(data-tooltip);
    display: none;
    position: absolute;
    background: #000;
    color: #fff;
    padding: 4px 8px;
    font-size: 14px;
    line-height: 1.4;
    min-width: 100px;
    text-align: center;
    border-radius: 4px;
}
/* Dynamic horizontal centering */
[data-tooltip-position="top"]:before,
[data-tooltip-position="bottom"]:before {
    left: 50%;
    -ms-transform: translateX(-50%);
    -moz-transform: translateX(-50%);
    -webkit-transform: translateX(-50%);
    transform: translateX(-50%);
}
/* Dynamic vertical centering */
[data-tooltip-position="right"]:before,
[data-tooltip-position="left"]:before {
    top: 50%;
    -ms-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -webkit-transform: translateY(-50%);
    transform: translateY(-50%);
}
[data-tooltip-position="top"]:before {
    bottom: 100%;
    margin-bottom: 6px;
}
[data-tooltip-position="right"]:before {
    left: 100%;
    margin-left: 6px;
}
[data-tooltip-position="bottom"]:before {
    top: 100%;
    margin-top: 6px;
}
[data-tooltip-position="left"]:before {
    right: 100%;
    margin-right: 6px;
}

/* Tooltip arrow styling/placement */
[data-tooltip]:after {
    content: '';
    display: none;
    position: absolute;
    width: 0;
    height: 0;
    border-color: transparent;
    border-style: solid;
}
/* Dynamic horizontal centering for the tooltip */
[data-tooltip-position="top"]:after,
[data-tooltip-position="bottom"]:after {
    left: 50%;
    margin-left: -6px;
}
/* Dynamic vertical centering for the tooltip */
[data-tooltip-position="right"]:after,
[data-tooltip-position="left"]:after {
    top: 50%;
    margin-top: -6px;
}
[data-tooltip-position="top"]:after {
    bottom: 100%;
    border-width: 6px 6px 0;
    border-top-color: #000;
}
[data-tooltip-position="right"]:after {
    left: 100%;
    border-width: 6px 6px 6px 0;
    border-right-color: #000;
}
[data-tooltip-position="bottom"]:after {
    top: 100%;
    border-width: 0 6px 6px;
    border-bottom-color: #000;
}
[data-tooltip-position="left"]:after {
    right: 100%;
    border-width: 6px 0 6px 6px;
    border-left-color: #000;
}
/* Show the tooltip when hovering */
[data-tooltip]:hover:before,
[data-tooltip]:hover:after {
    display: block;
    z-index: 50;
}

This was great except doesn't work in IE10 :/

Yes I just tested it and also wasn't surprised it didn't work .Good old IE! ;)

@JoshCrozier it helped a lot

html - How do I add a tool tip to a span element? - Stack Overflow

html css
Rectangle 27 162

It doesn't just convert non-Numbers to Number, it converts them to Numbers that can be expressed as 32-bit unsigned ints.

Although JavaScript's Numbers are double-precision floats(*), the bitwise operators (<<, >>, &, | and ~) are defined in terms of operations on 32-bit integers. Doing a bitwise operation converts the number to a 32-bit signed int, losing any fractions and higher-place bits than 32, before doing the calculation and then converting back to Number.

So doing a bitwise operation with no actual effect, like a rightward-shift of 0 bits >>0, is a quick way to round a number and ensure it is in the 32-bit int range. Additionally, the triple >>> operator, after doing its unsigned operation, converts the results of its calculation to Number as an unsigned integer rather than the signed integer the others do, so it can be used to convert negatives to the 32-bit-two's-complement version as a large Number. Using >>>0 ensures you've got an integer between 0 and 0xFFFFFFFF.

In this case this is useful because ECMAScript defines Array indexes in terms of 32 bit unsigned ints. So if you're trying to implement array.filter in a way that exactly duplicates what the ECMAScript Fifth Edition standard says, you would cast the number to 32-bit unsigned int like this.

(In reality there's little practical need for this as hopefully people aren't going to be setting array.length to 0.5, -1, 1e21 or 'LEMONS'. But this is JavaScript authors we're talking about, so you never know...)

1>>>0            === 1
-1>>>0           === 0xFFFFFFFF          -1>>0    === -1
1.7>>>0          === 1
0x100000002>>>0  === 2
1e21>>>0         === 0xDEA00000          1e21>>0  === -0x21600000
Infinity>>>0     === 0
NaN>>>0          === 0
null>>>0         === 0
'1'>>>0          === 1
'x'>>>0          === 0
Object>>>0       === 0

(*: well, they're defined as behaving like floats. It wouldn't surprise me if some JavaScript engine actually used ints when it could, for performance reasons. But that would be an implementation detail you wouldn't get to take any advantage of.)

+2 in depth description and table, -1 because array.length validates itself and can't be arbitrarily set to anything that is not an integer or 0 (FF throws this error: RangeError: invalid array length).

However, the spec deliberately allows many Array functions to be called on non-Array (eg. via Array.prototype.filter.call), so array might not actually be a real Array: it might be some other user-defined class. (Unfortunately, it can't reliably be a NodeList, which is when you'd really want to do that, as that's a host object. That leaves the only place you'd realistically do that as the arguments pseudo-Array.)

+1 for array.length = LEMONS. Have to find a really annoying person so I can play this trick on their code :3

Great explanation and great examples! Unfortunately this is another insane aspect of Javascript. I just don't understand what's so horrible about throwing an error when you receive the wrong type. It's possible to allow dynamic typing without allowing every accidental mistake to create a type casting. :(

Oh, and @yoshi, please don't! Let's not scare off those trying to learn...

What is the JavaScript >>> operator and how do you use it? - Stack Ove...

javascript operators bit-shift