Hacker News new | past | comments | ask | show | jobs | submit login
A Reintroduction to JavaScript (developer.mozilla.org)
321 points by psibi on Feb 3, 2014 | hide | past | favorite | 72 comments



I am currently in the process of re-learning JavaScript from scratch. And I found the light:

1. Douglas Crockford videos: http://www.yuiblog.com/crockford/

2. Eloquent JavaScript intermediate level tutorials: http://eloquentjavascript.net/contents.html


If you truly want to master the language, Reg Braithwaite's stuff is incredible. I think Javascript Allongé is one of the best programming books I've read on any topic, and it's free online: http://leanpub.com/javascript-allonge.


Excellent resource, thank you very much for posting!


If only it wasn't full of hipster coffee analogies…


Crockford is largely how I learned too. He's a crank but I've found that to be a useful property when I was learning JS. (Or really, re-learning it as you say)


Check out the book Effective JavaScript[1], too.

[1] http://effectivejs.com/


Crockford's "Javascript: the Good Parts" is a very good book.


The "even nicer [array for loop] idiom" is pretty cool:

  for (var key = 0, value; value = someArray[key++];) {
    // value is already defined by for loop
    console.log('index: ' + key, 'value: ' + value);
  }
Also, I finally understand closures:

"Whenever JavaScript executes a function, a 'scope' object is created to hold the local variables created within that function. It is initialised with any variables passed in as function parameters. This is similar to the global object that all global variables and functions live in, but with a couple of important differences: firstly, a brand new scope object is created every time a function starts executing, and secondly, unlike the global object (which in browsers is accessible as window) these scope objects cannot be directly accessed from your JavaScript code... A closure is the combination of a function and the scope object in which it was created."


That was a great way to iterate over a non-sparse array such as an array of objects... Back in 2006 when this article was written.

In fact, this was an even better way to write that loop in 2006:

  for( var value, i = -1;  value = array[++i]; ) {
    console.log( 'index: ' + i, 'value: ' + value );
  }
Basically the same thing except for the pre-increment instead of postincrement. In some of the browsers of that day (at least IE), preincrement was faster. And this version gives you the correct array index inside the loop, unlike the off-by-one in the other version.

I was so proud of myself when I discovered this alternative that I wrote a recipe for the jQuery Cookbook recommending it as the fastest way to iterate over a typical array of objects such as you might receive from a JSON request.

It also used to be a great idea to optimize your machine code programs by looking up the CPU cycles for each instruction. Fewer cycles = faster code.

Of course, that doesn't work any more, what with pipelining and out-of-order execution.

Alas, these nifty JavaScript loops are not the fastest any more either. Fewer operations != faster code.

The optimization guy for V8 explained this to me at Google I/O 2012. He said that V8 can optimize the heck out of references into an array where all the types are the same (either primitive values, or objects that all have the same properties). But if you ever try to reference outside the bounds of the array, it throws the whole thing back into deoptimized code.

And that is the problem. These nifty loops rely on reading the nonexistent element just past the end of the array. That's their termination condition.

It turns out that with modern optimizing compilers, the plain old traditional JavaScript loop is faster across the board:

  for( var i = 0, n = array.length;  i < n;  ++i ) {
    var value = array[i];
    console.log( 'index: ' + i, 'value: ' + value );
  }
(There is still a minor benefit to using preincrement instead of the more traditional postincrement in some modern browsers.)

I put together a JSPerf for this a while ago:

http://jsperf.com/mikes-loops/2

I was quite embarrassed to learn how poorly my clever loop works in modern browsers!


>I was quite embarrassed to learn how poorly my clever loop works in modern browsers!

What's really embarrassing is IE js performance.

Since I keep an ancient copy of of Netscape 9.0.0.6 on my computer I decided to try it so see how much browsers have improved. It doesn't seem to upload results I'll post them here in the same order as the testing page.

17.25 16.72 5.94 8.81 18.90 23.28 20.92 23.58

This is on the same computer that was pulling 5000+ on the fastest tests. Browsers have come a long way.


> Back in 2006 when this article was written

It is frequently and recently updated.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re...

Perhaps you should add your bit?


The above code will print out an off-by-one index for each element (starts at 1 and not 0).

Given that the loop also fails to complete if someArray contains a falsy value, I'd say this trick falls into the "too cute to be safe" category.


Unless I'm mistaken, wouldn't this loop terminate prematurely if the array contains any falsy value, such as undefined, null, false, NaN, or 0?


Yes, there's a note right after:

    Note that this trick should only be used
    for arrays which you know do not contain 
    "falsy" values (arrays of objects or DOM 
    nodes for example). If you are iterating 
    over numeric data that might include a 0 
    or string data that might include the 
    empty string you should use the i, len 
    idiom instead.


You're correct. Seems like a pretty useless/dangerous idiom to me. How often can you be sure that in 100% of cases your loop will never iterate a 0, an empty string or some other falsey value?


As of ES6 I would limit myself to only three styles of writing array for-loops:

1. Crockford's C style with cached array length (fast and flexible, but verbose):

  for (let index = 0, length = array.length; index < length; index += 1) {
    console.log(index, array[index]);
  }
2. Functional style (terse and flexible, but slow):

  array.forEach((value, index) => console.log(index, value));
3. Python style (fast and terse, but not flexible):

  for (let value of array) {
    console.log(value);
  }
By "flexible" I mean being able to e.g. iterate over items with odd indexes or in reverse direction.


Small problem with the conditional using the array assigment. If a value in the array is not "truthy", the loop will stop at that element -- e.g. ['a', 0, 'b', 'c'] will only print out the first element in your example.


The example of JavaScript's prototype here is the best I've ever seen! It's in the "Custom Objects" section.


Yeah it's good. The whole thing is nicely presented with great examples. Bookmarked.


Since I started using JS heavily lately, it's nice to be reminded of some things. Thanks for posting.

One question though, it says:

    If you want to append an item to an array, the safest way to do it is like this:
    a[a.length] = item;  // same as a.push(item);
a.push() variant seems more elegant to me. Why is a[] variant "safer"?


It must be for the compatibility, Array.prototype.push() has been added to IE 5.5:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...


Thirteen years ago... I would argue that you could use a.push() safely now.

So, why should a[a.length] be safer?


He said it already, JUST for the compatibility. No other reason compared to push nowadays.


Both methods are equally safe, what the author meant is that both are safer than a[14] = item or a[myCounter] = item.


Off-topic, but I must say that this site handles resizing very well. I really appreciate it when a website seamlessly transitions from desktop-size to mobile-size layout. Sometimes I just like having my browser window shrunk down (or zoomed in for viewing from farther away), which means that with most sites I have to scroll horizontally, which is not very usable.


It is probably a good idea to add 2006 to the title since that's the date of the last update [1].

1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re...


It's a wiki, see the page's history: https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re...

Maybe remove the "2006" from the headline (again).


Not able to edit the headline now.


I've altered it today, fixed in MDN nice catch thanks.


Is that the last date? There's a mention of pre-2013 on the page?

Edit: Just noticed inglor say it was a caching issue and the page was updated today.


Thanks, updated the title.


read author's comment above.


Some mistakes there, will fix. `null` is most certainly not an object.


I got this in an interview once as a curveball. It's most certainly an object in Javascript!

  > typeof null
  "object"
Contrast that with:

  > typeof undefined
  "undefined"
Go figure :)


That's a mistake in the specification. We tried to fix that experimentally but it broke too many sites.

If you check the language specification you can see that `null` is in fact not an object - it's something called a 'primitive value type', just like numbers, strings, undefined and booleans.

Here http://es5.github.io/#x8 :)


Can you reconcile what you've just said with this excerpt from your guide:

> There's our first brush with JavaScript objects! Did I mention that strings are objects too? They have methods as well

Also, how do NaN and infinity fit in? I'm guessing they're special cases of Number types?


    "hello"
Not an object.

    new String("hello")
Object.

Along the way, autoboxing will convert a string to an object delegating to String.prototype if you write something like "hello".foobar(). But primitive value strings are not objects.


Good question. First - this is _not_ my guide. MDN is a wiki and anyone can edit it.

- NaN is just a number type . You have NaN in Java or C++ too. It's a way to represent "a number we can't represent"

- Good catch on strings, I'll edit it in.


> Also, how do NaN and infinity fit in? I'm guessing they're special cases of Number types?

Those are magical values from IEEE 754.

IEEE 754 is also the reason why there is a signed zero or why division by zero results in +/- Infinity.

  >>> 0 === -0
  true
  >>> 1/0 === 1/-0 // compares Infinity with -Infinity
  false


typeof null returns "object", but I do not believe it is correct to claim that null "is an object". It is my understanding (maybe a misunderstanding, I will happily state) from reading a ton of comments from Brendan Eich in various places that typeof null is "object" for historical reasons involving the way reference types were implemented in the original JavaScript VM.


It is correct to say that typeof(null) returns the string 'object' because of a bug that is now written into the standard to prevent old software from "breaking" if they fixed this.

It is not ever correct to say that null in JavaScript is an object. Just ask javaScript itself:

    Object.getPrototypeOf(null)
      //=> TypeError: Object.getPrototypeOf called on non-object


Exactly, if people are interested I'll gladly find the reference to the relevant esdiscuss thread.


Douglas Crockford on the history of this behaviour:

https://www.youtube.com/watch?v=v2ifWcnQs6M#t=489


In JavaScript there are two instances where typeof lies. One is with null the other is with function.


Ok fixed them.


still a better introduction to javascript:

https://www.destroyallsoftware.com/talks/wat

(with a little bit of ruby)


No. It's not a good introduction to JS. JS is very WTF worthy (I should know, I'm writing a book on how to write asshole Javascript), but the WAT talk is NOT a good intro


Agreed, it's a collection of trivia. Very WTF-worthy trivia but if your code is doing basically any of the things listed in that talk, something has gone terribly awry.


"We've introduced another keyword: 'new'. new is strongly related to 'this'. What it does is it creates a brand new empty object, and then calls the function specified, with 'this' set to that new object"

Perhaps it would be worth to mention that 'new' not only sets 'this' to be the empty object but also return that object to the location where new was used.


I've read this article a couple of times in the last few years and it never ceases to amaze me. Clearly and in a concise way it lists all the points that people usually miss about JS.


"if you're used to math in C or Java. Watch out for stuff like: 0.1 + 0.2 == 0.30000000000000004"

Uh, how floating poing operators are different than this in C or java


One of my favorite tutorials from John Resig: http://ejohn.org/apps/learn/


I didn't know about the memory leak stuff! Any tools out there to help identify this in your code?


There's Dynatrace, IESieve and Drip (the latter two's websites are now defuct though), but IIRC, the IE team fixed the memory leak issue via a service pack or hotfix a few years ago.


if that's was it's first name it should be renamed back to LiveScript


"It was originally going to be called LiveScript, but was renamed in an ill-fated marketing decision to try to capitalize on the popularity of Sun Microsystem's Java language "


Feel free to start calling it that.


Old but gold.


If you wanted to find a friend for someone would you keep trying to introduce them to same stupid ugly person, while saying: "Look! He/she is wearing make-up this time!".


This isn't a productive comment.

Whether you like it or not js is here to stay. It's the language of the web (and more). A lot of new capabilities are being exposed via browser makers (e.g peerconnection, webrtc) which only serve to increase its power. Calling it stupid and ugly is your unsubstantiated opinion. (Infinitely more useful: say why this is your opinion.)

I think this is a nice intro to the language. Why it's being posted now though is a little puzzling considering it's from 2006. It is obviously still relevant and interesting but readers should realize it's not very recent.


I've never gone very deep with JS. Anything you could recommend, off the top of your head, for a more recent look at the language?


There has been added a lot of new features to the browser, but the core language (EcmaScript) has not evolved much for a while.

* Overview: https://rawgithub.com/whatwg/html-differences/master/Overvie...

The next thing is JavaScript "next" or Ecma Script 6

* http://wiki.ecmascript.org/doku.php?id=harmony:proposals

You can use Traceur if you want to try out ES6 features today More info: https://github.com/google/traceur-compiler

These days there is a lot of things going on in the tooling section

Build: * Grunt: http://gruntjs.com/ - a lot of grunt- tasks at http://npmjs.org/ * Newest kid in town: https://github.com/gulpjs/gulp

Modulization and dependency management: * http://en.wikipedia.org/wiki/CommonJS * http://browserify.org/


JavaScript Spessore, by Reginald Braithwaite:

https://leanpub.com/javascript-spessore


Thank you, although please note that "JavaScript Spessore" is (a) a work-in-progress, and (b) about "Thinking in objects" more than "The idiomatic way to program in JavaScript.



> js is here to stay. It's the language of the web

In the same manner as assembler is here to stay. Assembler is "the language of the computer". Not that many people write assembler these days though, majority moved on to languages more suited to their needs.


You got the metaphor wrong.

"Hey, look, this is Jenna. You'll have to work with her for the next 10 years. She's hard to figure out and grumpy at times, but if you treat her right she'll play along. Actually if you get to know her, she can be a great asset."


Please stop blaming users. If Jenna is a royal pain in the ass by design, her being a pain in the ass isn't the user's fault for not "treating her right." Whether it is an asset to work around her crap or not. There's all kinds of things which are an asset to know but are a huge pain in the ass to work with, and somehow we are allowed to complain about most of those but god help the man who complains about Jenna in public. She's connected.


Paul Graham once said, "Where there's muck, there's brass." He explained that there is often an opportunity to be had if you dive deep down into ugly, unpleasant things and find a way to make them work.


http://www.phrases.org.uk/meanings/408900.html

"Don’t make idols for yourselves" is another old expression.


“Everything that can be written in JavaScript will eventually be written in JavaScript”. – Atwood’s law "Everything’s Gone JavaScript" "The future is written in Javascript" JavaScript is now an integral part of several operating systems. JavaScript is also moving quickly into the hardware world.


Did you just mean Java 7?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: