Hacker News new | past | comments | ask | show | jobs | submit login
A re-introduction to JavaScript (developer.mozilla.org)
290 points by hikz on May 9, 2015 | hide | past | favorite | 109 comments



I think there's no point trying to avoid memory leaks in older versions of IE. Circular references due to closures are too common and it's not worth messing with your code.

IE users are probably used to getting a horrible user experience anyway. I'm sure they can cope with a few browser freezes/crashes every once in a while - They know how to take a beating :p


The reason this is mentioned (and things like the part about caching array length in your for loop) is that this tutorial was mostly written back in 2006, when things were obviously a bit different with JavaScript.

The article has gotten updates since then (check the history), but not many and not to the extent it probably needs. Not sure why it keeps getting linked.


Since you seem to have an understanding of what is wrong with it, care to tell about everything you know that should be updated?


I would find that helpful. Since the article is a wiki, I would be willing to edit in any suggestions that magicalist makes, if magicalist doesn’t want to bother doing the editing him or herself.


There's definitely no point to avoid them for IE. The point as I see it is that it should be avoided for every browser.

Indeed IE's users are having terrible experience anyway, but let's just don't push FF and Chrome to their memory limits, just because we don't care with our code.

One of the best parts when I develop client-side web-apps is the debugging and looking close what the garbage collector is doing. For example : I usually don't use `delete` keyword, since I know it might create a node that GC's can't clear.


Can you expand on what you said about the `delete` keyword implications with the GC? I've never heard of that issue.


I haven't either, only that delete will cause code to be de-optimized.


Its main purpose is deleting a property from an object, which is a pretty slow operation on modern JS engines. Unless some code tests for the existence of a property, setting it to null is a better idea.


I'd suggest undefined over null if you want to effectively remove a property, since JSON.stringify won't serialize those properties... in an array, it will become null.

Though, I don't use delete much, I honestly don't worry about it much. In most contexts it's a bit of a premature optimization unless you are in a very low-level tool that will be used for example gaming, video or photo manipulation, there are probably better optimizations to make.


I think it affected earlier versions of IE - Douglas Crockford detailed an issue here:

http://javascript.crockford.com/memory/leak.html


What the hell is wrong with people today? I was hazarding a guess what was being referred to and I get down voted?


It was very important for IE <=6. Early AJAX web apps like GMail ~2004 were quite hard to get right - avoid most memory JS leaks or the memory consumption got out of hand too fast. That was in the days of 512 MB memory and WinXP.


I worked on an extjs app for a company where most of the users at the time where IE6 corporate wide (this was several months after IE8 was available. That said, there were such horrible memory leaks with references just in the nature of the application under IE (component<->JS ties wouldn't unwind/gc) it would quickly eat up memory after about half a day of work would need to restart the browser...

In the end a lot of people using the application would either have to restart during the day, use portable Firefox, which many actually did. Of course, there are/where many worse things in practice dealing with supporting IE<9 for relatively modern web applications. I'd still rather deal with that, than the v4 browser days.


I was stunned when I read the part about hooking the "this page is done now, let's go to another" event to manually clean up memory. (Old) IE worse than failure, indeed.


"While often derided as a toy"

Javascript is not a toy; toys are fun.


I like JavaScript but that did make me laugh.


What could be more fun than a language that says the result of dividing by 0 is "Infinity"? It's a hoot!!


That's from IEEE 754 (a standard for floating-point arithmetic). `NaN` and -0 exist for the same reason.


To be fair, just because something is a standard doesn't mean it isn't a dumb implementation. Just by testing the programming languages on my computer, I can tell you that Python, C, and D all throw errors rather than allow it, which is the smart thing to do.


> I can tell you that Python, C, and D all throw errors rather than allow it

Python throws an error, but numpy.divide(1., 0) will work just fine (and return inf).

I'm not sure why you're saying C throws an error. The behavior of dividing by 0 is undefined by default, but on most machines these days the hardware implements IEE-754 and the C implementation will advertise as implementing IEC 60559, so 1. / 0 will give you inf as well.


Trying to compile a test program with Clang threw errors, and bringing up numpy is disingenuous.


Are you sure you were using floating point math? Compiling 1.0 / 0.0 should not give errors or warnings. 1 / 0 will, on the other hand.


I know, I was just joshing! Man, you guys really didn't like that one. Personally I enjoy taking a moment now and then to reflect on some of the sillier aspects of JS. This is because I love JS, not because I hate it.


The article mentions an idiom for iterating over an array. It says 'an even nicer idiom is...' and then it shows it.

I just wanted to say that the behaviour of this 'nicer' idiom may not be what's expected - it stops iterating once it hits the first falsy value. I was quite excited actually when I first saw them idiom, until I quickly realized its limitations


Yeah and not a big fan of them saying you can do for...in on an array while casually mentioning the limitation of doing such. I would consider it far better practice to NEVER iterating over an array with for...in.


Is there even any guarantee it would be iterated in the correct order?


Nope. Then again if you're doing a for...in you probably don't care about order.


Oh jeez, I just saw that the section you're referring to repeats the old canard about caching the length of an array when iterating over it. Come on, that can't still be good advice. It always struck me as ridiculous to begin with, but almost certainly now it's optimized away.

Not to mention the suggestion you're talking about, which I bet would bite programmers for the reason you mention. Seems like a bad idiom, I've personally never seen it in the wild.


I think nearly every JS engine now optimizes `for (...;i < arr.length;...)` -- I'm nearly 100% sure V8 does and fairly certain Firefox's and ModernIE's do as well.

In fact, even `for` is likely an over-optimization. In nearly all JS code you can get away with just using `forEach` (or its friends).


forEach is awfully slow compared to a for statement if you're dealing with numbers - less so with strings/objects, but it's still noticeable (like 10x whenever I've tested it at best).

Caching the array length still gives you a small speed boost in most browsers, but it's probably an over optimisation unless you're doing something really intensive.


If you're doing number crunching, yes, don't use forEach.

If you're just writing ordinary business code (i.e. in 80% of all code out there), by all means, please use forEach and friends.

Besides, if you're doing number crunching in JS, you probably want to stick to ASM.js anyway.


I think a big reason to cache the array length within interviews (for cases when it isn't already cached) is that to not do so can often increase the complexity of a solution by a factor of O(n).


the problem with using it even when you don't have falsy values is that, eventually, you're going to forget that you can't use it when you do have falsy values. You're going to get too comfortable with it, and it's not general-purpose enough.

Can't wait for ES6 to no longer be 'experimental', as I'd much prefer to use 'for..of' loops


Honestly, I'm more excited about some of the ES7 features at this point... I've given in, as much as I dislike transpiling, and using BabelJS for most of my new development, server and client-side.

On the server-side async/await are worth their weight in gold... and using lambdas is very nice. I still don't like the ES6 module syntax over node/commonjs require statements though.

The only thing to be really mindful of is when you browserify for the client that you don't accidentally include, for example the entire crypto library, buffer or similar shims because they can get very big, very quickly.


>old canard about caching the length of an array when iterating over it

I think there are still places where you need to do this (please correct me if wrong, or mention some other cases):

- when iterating over DOM nodelists in JS (why doesn't the browser cache this as well?)

- if using strlen in C/C++ (for the latter, you should use string.length() instead).


Also seems weird that they don't mention `forEach`.

(Sure, IE<9 is a caveat, but all the Array iteration methods are the easiest things to shim and if you're targeting below IE9 chances are pretty good it's not the first shim you'd be using.)


I improved the wording:

“A nicer-looking but limited idiom is:”

MDN documentation is on a wiki. You can just edit the page.



These are all roughly a year apart and it's a very interesting article. I don't really see a big problem with reposts that far apart to catch newcomers' eye.


I've only been here for a couple of months and this was nice to see.


[flagged]



"Please don't insinuate that someone hasn't read" the Hacker News Guidelines...


I'm not insinuating, I'm telling you.

Incidentally, can you not see the irony of your own statement? Please, stop with your valueless comments. This article is and remains a perfectly valid submission to HN.


According to the guidelines, I should charitably interpret that you have read them. Which means, charitably, you are ignoring them.


Very nice to see it starts off with a (correct) discussion of JS types! JS devs mostly don't know the actual types in JS, which is pretty crazy if you think about it.


I think 99% of the problems people have with Javascript are not actually types, but `this`.

It's the most confusing part about Javascript. This context, var foo scope, what? Why is this value not updating? undefined? What???


I actually found the Javascript 'this' keyword more understandable after working with Python.

  >>> class foo():
  ...   def test(this, x):
  ...     print this, x
  ... 
  >>> x = foo()
  >>> x
  <__main__.foo instance at 0xb71928ac>
  >>> x.test(1)
  <__main__.foo instance at 0xb71928ac> 1
  >>> y = foo.test
  >>> y(1)
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
  TypeError: unbound method test() must be called with foo instance as first argument (got int instance instead)
  >>> y(x,1)
  <__main__.foo instance at 0xb71928ac> 1
In Python, the reference to the current object is an explicitly declared parameter in the method definition, but the parameter is passed implicitly - the value of "this" is whatever is comes before the period when the method is called. If you call it in any other manner, it throws an unbound method error. Javascript is the same way, but instead of throwing an error it will instead pass 'window' implicitly. The equivalent code in Javascript:

  function foo() { }
  foo.prototype.test = function(x) {
    console.log(this, x);
  }
  var x = new foo();
  x.test(1); // prints VM1061:4 foo {test: function} 1
  var y = x.test;
  y(1); // prints VM1061:4 Window {top: Window, window: Window, …} 1


Actually, what you get when referencing x.test in Python is a bound method:

  >>> foo.test
  <unbound method foo.test>
  >>> x.test
  <bound method foo.test of <__main__.foo instance at 0xf74d68ac>>
  >>> z = x.test
  >>> z(123)
  <__main__.foo instance at 0xf74d68ac> 123
I really like this behavior in Python. Unfortunately, JavaScript does not behave the same way, as you see in the last couple of lines in your example. You can however get the same result by manually binding the method to the object:

  z = x.test.bind(x)
  // z is: function () { [native code] }
  z(123)
  // foo {test: function} 123


I came (back) to JS after doing a lot of Python and I think that may have helped understanding `this` in JS.

Note that the behaviour of `this` defaulting to `window` (or `global`) is only the legacy behaviour. You should be using strict mode (there's really no justification not to -- except for extremely rare edge cases, e.g. having to delete global variables without having a reliable reference to the global object other than `this`).

In strict mode, `this` would be undefined. As expected, if you consider `x.y()` syntactic sugar for `x.y.call(x)` (and therefore `z()` syntactic sugar for `z.call(undefined)`).

Under the hood, invoking a function translates to a call of the functions `[[Call]]` method, which takes an explicit `this` just like `Function.prototype.call` does.


I find that testing works better when I define my functions separately from binding in objects.

  var foo = {
    doSomething:(...argv)=doSomethingMethod(foo, argv)
  };
  return foo;
In this way, the execution is always predictable, as I avoid the use of this altogether... It's my one niggle with koa, that it uses this (execution context) as the request/response context. I tend to it in practice.

It's similar to what Crockford now presents as a preferred approach in dealing with having context for functions... I just like discrete functions that can be tested independently of their execution context... by passing the context as a parameter, this becomes explicit... with binding, the process becomes transparent.


Using jspm, SystemJS and Babel for my latest project, and simply using let universally over var and arrow functions over anonymous functions has made this aspect of JavaScript behave like any sane language would.

I simply don't ever need to think about it anymore.


I agree, `this` is a disaster. But, I just can't hardly think of another language where the people working in it mostly don't know the types. (Well, OK, PHP devs probably mostly don't)

And I don't just mean run-of-the-mill blub programmers who dabble in jQuery, I mean some of the best devs I've ever seen in any language. I had a self-proclaimed JS expert tell me that JS has integers and floats as distinct types. Even the people I work with every day who are fantastic did not know that function and array are not types.

Of course, things like `typeof` don't help the situation, so I don't put the blame squarely on programmers' shoulders. And obviously you can get a lot done without knowing that, technically, functions are just objects that can be called. But it still strikes me as kinda crazy.


"technically, functions are just objects that can be called"

How can you create an object which can be called like a function, but will respond to 'typeof' with 'object' rather than 'function'?

What happens when you try to call an object - what's the error? Try it, in a few of your favourite javascript interpreters:

    ({})()
It seems clear to me that functions are more than "just" objects in JS. You can't start out with a random {} and turn it into a function. JS functions are a subtype of JS objects, but they are a distinct type. You can't substitute an object where a function is expected - you get a type error - but you can substitute a function where an object is expected.


> How can you create an object which can be called like a function, but will respond to 'typeof' with 'object' rather than 'function'?

You can't, by definition. Here is the relevant section of the ECMAScript 5 spec: http://www.ecma-international.org/ecma-262/5.1/#sec-11.4.3

Basically, an object which implements call will always cause `typeof` to return "function". But the broader point is that `typeof` will lie to you and you shouldn't trust it for, you know, determining the types of values. (For example, the type of null is null, but `typeof null` returns "object".)

As I noted above, this behavior of `typeof` is part of what causes the confusion around types in JS devs.

> You can't substitute an object where a function is expected - you get a type error - but you can substitute a function where an object is expected.

This is true, but not inconsistent with the notion that functions are objects which can be called. I encourage you to read the spec I linked above, or a draft of ES6.


There's types as defined in a spec, and types according to type theory.

In short, I think the spec is incorrect in its use of the concept of types; or incomplete.

You'll note that the spec uses the concept of "internal properties" to distinguish between the different things one can do with values. From a type theory perspective, these internal properties and the implied permitted operations come close to type definitions. It's a matter of perspective, then, when one is using the word 'type' as defined by a particular language's spec, or 'type' as in programming language pragmatics / type theory POV. For the generalist programmer who knows more than one language, a broader concept of types is usually more useful.

Further, the spec uses these internal properties solely to define the semantics of the language, and they are not necessarily visible artifacts of any implementation. Talking about them as if they were concrete confuses the map with the territory.


>Basically, an object which implements call will always cause `typeof` to return "function".

Are there any implementations which actually do this? In Node:

typeof({ call: function () { } }) --> 'object'

({ call: function () { } })() --> TypeError: object is not a function



and 99% of those 99% problems can easily be solved with the correct use of .bind() or .apply().


Especially when you need to do something like:

  var that = this;


That's not generally necessary in ES6 when you use "=>" to define functions. Javascript is getting better...


What happens when you nest anonymous functions? Would you have to use the arrow operator at every level?


It's really a minor criticism and I know ES6 resolves the issue :-)


Through bind of course, for the silly person who downvote me. Helps to have strict mode on. Happy to have educated you!


Looking at you Ember. Ugh!

    var controller = this;
    
Every time!


They have to. There's a bug in the JavaScript spec that makes you do this :-) they are perfectly correct in doing what they are doing, if they didn't then funny thing would start to happen. Sad, but true.


Uh, what's the reason for the downvote?


Probably because when you editorialize in your comment, you may get an adverse reaction.


Not the first to complain about this behaviour. In fact, if you run in strict mode now, ES5 requires you to use bind, call or apply - it won't box this to the global object but will return undefined.

Why do you think they decided to do this? Strict mode is to allow folks to transition their code to the new standard - and the new standard has made this decision to fix a flaw in JavaScript - it acknowledges its a hack to return the global object in this case.

So I'm less editorialising and more pointing out what is already known. Hope this helps.


Perhaps that the reason for that is not some "bug" in JS?


Except that for many, it is. If you extract a function in an object and allocate it to a global function, and that function calls on "this", then it's fairly obvious that the function cares about the object and not the "this" of the current scope.

It's why ES5 has bind to get around this.

Example from MDN [1]

  this.x = 9; 
  var module = {
    x: 81,
    getX: function() { return this.x; }
  };
  
  module.getX(); // 81
  
  var getX = module.getX;
  getX(); // 9, because in this case, "this" refers to the global object

  // Create a new function with 'this' bound to module
  var boundGetX = getX.bind(module);
  boundGetX(); // 81
To make the above example work without bind, you need to take a copy of the reference to this, And use that copy. Thus the kludge:

  var module = {
    x: 81,
    that: this,
    getX: function() { return that.x; }
  };
Of course, if you run in strict mode (ES5) the original example will return undefined, because you are now expected to specify this via call, apply or bind.

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


> You can also use the unary + operator to convert values to numbers:

    + "42"; // 42
> [...] However the "+" operator simply converts the string to NaN if there is any invalid character in it.

Being a bit pedantic here, why not recommending the Number function which may be less obscure for beginners?

    Number("42"); // 42


If you use a double NOT ~~"foo" you will always get a finite int32 value... which is useful when you can use 0 as a "default" representation. For that matter, all bitwise operations will coerce a value to an int32 representation. Which is something to be aware of, if you want larger integer values (< 2^53 - 1 and > -2^53 + 1).


Number() also converts to NaN if it's not a number though I would still avoid the + operator here because it is code smell (looks like you forgot your variable to concat).

Number automatically accepts exponent notation and auto-converts to hex (ignoring octal). parseInt() auto-converts hex and octal unless a radix is specified, but it also ignores the remaining non-number characters at the end of the string.

There isn't a single method that does whatever you want.


the String function is also a nice way to cast a value to a string (using .toString() is unsafe because it may not exist, such as with undefined and null): String(42) === "42".

An other thing that could maybe be covered is this specifity:

    typeof "42" === "string"
    typeof String(42) === "string"
    typeof new String(42) === "object"
Native constructors are ... fun beasts, to say the least.


Another way to cast to a Number is the bitwise-or operator. It has the useful property of always yielding a number.

    '42' | 0;      // 42
    NaN | 0;       // 0
    null | 0;      // 0
    undefined | 0; // 0
    false | 0;     // 0
    true | 0;      // 1


Bitwise operations don't produce Numbers (f64), but signed integers (i32).


> produce...signed integers

Well, except for right logical shifts.


It always yields an integer, so it's useful if you know you want an integer.


Correct me if I'm wrong, but I thought that the unary operator and the Number constructor yield equivalent results?


Since calling constructor functions without `new` is generally an error, I'd rather use `parseFloat`.


> Since calling constructor functions without `new` is generally an error

The behavior of Number, Boolean, String, and Array is well-defined, it's safe to call them without new. In fact, in the case of String/Boolean/Number, calling them with new will often do something you don't expect. (Calling them with new gives you a Number/String/Boolean object, not primitive, which can cause trouble when you try to compare them with ===, unless you remember to use their `valueOf` method)

Also, as noted below, it's possible for objects to not have a `toString` method, so attempting to call it to get the object's value as a string could blow up. So it's actually safer to coerce to string by adding an empty string or passing to String().


> The behavior of Number, Boolean, String, and Array is well-defined, it's safe to call them without new.

ES6 is packed with weird but well-defined things.

The problem is that calling a constructor function (a PascalCase'd function) without `new` looks like an error because it generally is an error. To make matters worse, without closely examining that function, you cannot tell if it's an error.

I do know that `Number()` happens to be one of those constructor functions which not only work without `new`, it also happens to behave differently when `new` is missing. It does not return an object. It returns a primitive.

Someone who doesn't know about this unusual secondary function will waste some time if they spot this apparent mistake.

Now, to defuse this time-wasting trap, you could either add a comment... or just do the sensible thing and write it in a way which does not require a comment.


That's fair, I just find them super useful in various situations, for example filtering over an array with Boolean to remove falsey values.


Yes, that's a good suggestion. Boolean works as well, for coercing to boolean of course.


Because Number(...) uses more bytes on the wire.


Whoa, the closure-based circular reference memory leak thing, is that just an IE issue or is that a language level (anti) feature? I need to know because I've very often done something like:

el$ = $('#whatever'); el$.click( function() { el$.find("a").css("color", "red"); } );


I think it's much easier to forget about "types" and think of objects instead. Trying to divide JavaScript objects into "types" will surely get you frustrated. If you absolutely want to check what "type" an object is, for example a sanity check for arguments passed to a function, you should make your own isMyType(obj) function and not rely on typeof or toString.


I think if you simply accept that there is no spoon, and that any utensil can be coerced and used as a spoon you will be much happier.

In general, the only niggle is when you want a discrete integer value, where zero is an acceptable input, or a string that represents a number coerced into a number.. but anything else to be null. You have to single out falsy values that aren't zero in this case.

Other than that one niggle in practice, I've come to truly appreciate the expressive nature that JS actually offers in practice. The additional concepts added in terms of ES6 and ES7 are pretty welcome. Though in practice, I've moved very far away from trying to apply many OO patterns of classes, inheritance, etc in favor of basic object instances, and functions that can be combined/composed.

It's pretty nifty all around.


The article says to watch out for 0.1 + 0.2 not exactly equalling 0.3 , so as a complete newbie to JavaScript, how do you work around this ?


This is not a huge problem as if you are outputting the floating point number, you would probably want to round it anyways. The biggest 'gotcha' is when doing equality comparisons between these numbers.

Consider the following:

    .1 + .2 == .3 // false
The way to 'get around' this is to have a value (usually called an epsilon) that is relative in magnitude to the numbers being compared. In this example, a value like .00001 as epsilon should work fine.

Anyways, all you have to do is check if the absolute difference of the numbers is less than the epsilon:

    var a = .1 + .2, b = .3, epsilon = .00001;
    console.log(Math.abs(a-b)<epsilon); // true
In short, try to not put yourself in a situation where you have to compare equality with doubles.


Floating point numbers in any language are inaccurate, if you're performing say, financial calculations then you can use fixed point numbers by using scaled integers. For example:

    var SCALE = 100; // 0.01
    
    var a = 0+1 * SCALE;  // e.g. 2.5 would be 2+5 * SCALE
    var b = 0+2 * SCALE;
    
    if (a + b == 0+3 * SCALE) {
      // this will work...
    }

    console.log(a / SCALE);


Is not a JS only thing, investigate how floating point values work.


Well other languages often offer decimal, or higher precision floats, right?


Not really. Most languages don't have a built-in decimal type, it's usually just a library feature. Higher precision floats won't help you either, as adding more decimal places won't make 0.2 == 0.3, it will just make the difference between them slightly smaller.


Yes, .NET is a good example with a decimal type with:

Approximate Range -> (-7.9 x 1028 to 7.9 x 1028) / (100 to 28)

Precision -> 28-29 significant digits

https://msdn.microsoft.com/en-us/library/364x0z75.aspx


right, but I think he first needs some insight on how IEEE 754 floating point arithmetic works.


See if there is a fixed precision arithmetic library for JS? (similar to BigDecimal in Java / Groovy)

Homework: 1) Google for such; 2) see which one doesn't suck.


Groovy is a heavily marketed programming language that uses BigDecimal, just like its sister dynamic languages Clojure, Rhino/Nashorn, and Xtend also do. Only Java actually ships BigDecimal.


Yeah, I get that the base JRE is what actually provides the BigDecimal class in this case -- the other languages just use it. (as the default "decimal"-numeric type in the case of Groovy, rather than [Dd]ouble)


"JavaScript is an object oriented..."

No it isn't. It has support for OO and you can choose to write code object-oriented if you wish. But equally you can disregard the OO bit quite happily and compose behaviour using closures instead.

None of my favourite JS libs are OO, it's a poor abstraction imho.


This is a really good overview.

Along the same line but more in depth, I really like Cody Lindley's JavaScript Enlightenment:

http://www.javascriptenlightenment.com/


For the second example on the memory leak section (https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re...), wouldn't just changing "el.style" to "this.style" fix the memory leak?


I wish there were more tutorials of this style, for people who are already familiar with programming and just want to know how a language works.


One caveat not mentioned is that while float is 64 bit floating point number, int is only 53 bit integer, unlike having 64 bit int in most other languages. Yeah, I've got bitten by this before causing a nasty bug.


There is no "int" or "float" (mostly[1]) — there is only Number, which is an IEEE floating point. A literal `1` is a floating point that happens to be precisely representing an integer. "53 bits" happens to be the limit of consecutive integers that you can store in an IEEE double.

[1]: 32-bit integers show up under the hood, in expressions such as `5000000000|0`. Both 0 and 5000000000 are precisely represented in JS's Number type, but you cannot (correctly) take a binary OR of the two.


As far as I know 53-bit integers are a bit haphazard in JavaScript - it's best to stick to 32-bit unless you really know what you're doing.


The biggest gotchas with whole numbers in JS (IEE754 64-bit floats) is that in JS all bitwise operations are performed on a 32-bit integer under the hood... in practice this means you can do a bitwise operation on anything and it will be coerced into a 32-bit integer, either first via the parseInt(X,10) path, or becomes an empty 0 value.

It really isn't unique to JS, and there are several bignum libraries that can/will help.


Cool. Did Brendan Eich write it? What's he doing these days?

Keep up the good work Mozilla.

edit: I see MANY people contributed! You can too! https://developer.mozilla.org/en-US/docs/Mozilla/Connect. It still would be cool if Eich could act as an "editor" to JS related articles!


Rediscover Javascript, by using :TypeScript, CoffeeScript or Node.js and a gazillion of slightly incompatible web frameworks ... I wish DART had been there in the beginning.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: