

Learning Advanced JavaScript - bensummers
http://ejohn.org/apps/learn/

======
edd
This has already been posted once. You can read the comments from that time
here: <http://news.ycombinator.com/item?id=823347>

------
cturner
I look at <http://ejohn.org/apps/learn/#2> and think once again - javascript
is a _disgusting_ language to read. Objective-J is nice and all, but what I
really want is a self-like syntax for it
(<http://en.wikipedia.org/wiki/Self_programming_language>). I've struggled to
learn ometa and wish I found it easier.

------
bumblebird
Slightly off-topic, but:

>> #2: Goal: To be able to understand this function:

idk, I find all the js library bind() functions to be a bit yucky. Closures
aren't hard:

onclick = function(c){return function() {
c.doSomething(stuff,theOtherStuff);}}(this);

Also, they're far more general when you write them like that, and you're not
asking the runtime to constantly call array methods etc

Useful resource though, but don't use a js lib :)

~~~
jacobolus
They’re much less readable when you write them like that, because when you get
a few dozen lines down, _this_ is much clearer than _c_ , especially for
people trying to read your code who are used to writing idiomatic JavaScript.

Also, I can live with defining such an argument on initial definition, as with
Python’s _self_ in method definitions, but having to add an extra argument to
every function/method _invocation_ for the execution scope, that must be
passed in every time explicitly or everything breaks, is really obnoxious. You
could certainly make up a convention for the proper name, but just using
_this_ is more straight-forward, and doesn’t _really_ have any particularly
significant downsides.

There’s a reason that pretty much every JavaScript framework includes a _bind_
function/method, and that they’re adding it to the official language spec:
it’s a convenient and effective pattern.

~~~
bumblebird
Sure, once it's in the language spec and doesn't use Array hacks.

~~~
jacobolus
What’s an “array hack”? Using _Array.prototype.slice_ on the _arguments_
object? You’re going to have to provide some evidence that language designers
didn’t intend that to be possible, before you criticize it. It works perfectly
well in every JavaScript implementation. From my perspective, it’s quite often
the only reasonable way to deal with the _arguments_ object, and one of the
most powerful and flexible ways of making functions with useful APIs in
JavaScript.

~~~
bumblebird
Turning an object into an array isn't a nice way to do things IMHO. Maybe
runtimes optimize for these cases, or maybe they create completely new objects
every time and you get fantastic object churn.

Yes it works well, but it's not really necessary. It's inefficient wasted
effort.

I guess it's fun to make lovely APIs, but that doesn't help people who just
want their js to run fast.

~~~
jacobolus
> _Turning an object into an array isn't a nice way to do things_

This doesn’t happen. The object is unchanged when you call array.slice.

> _Maybe runtimes optimize_

Only insofar as the built-in array methods are optimized anyway.

> _maybe they create completely new objects_

No, they don’t. Or rather, yes, array.slice creates a new object to put the
slice in, but only because that is part of its declared API.

> _Yes it works well, but it's not really necessary._

What’s the alternative?

> _It's inefficient wasted effort._

Inefficient how? If you time it, it’s faster other ways of accomplishing the
same thing. Whose wasted effort? It certainly saves me time as a JavaScript
developer.

* * *

To be honest, I think that _arguments_ should just _be_ an array (then we
wouldn’t have any of this trouble), but I assume that’s not possible for the
language at this point.

~~~
bumblebird
>> This doesn’t happen. The object is unchanged when you call array.slice.

You're wrong. Why don't you check instead of reading API docs or saying what
you think _should_ happen? It obviously is changed, and is a new object:
Array.prototype.slice.call({0:"hello",1:"world",foo:"bar",length:2});

Results in ["hello","world"] - the result is a completely new object -
inefficient wasted effort. Both in cpu and memory.

Offtopic again, but here's an interesting way to make a new N element array,
initialized with undefineds...

Array.prototype.slice.call({length:100}) = [undefined, undefined,
undefined........ undefined]

Array.prototype.slice.call({length:10000000}) takes almost 1 second to run on
my MBP while it's creating that new array.

>> What’s the alternative?

As I say, just write closures...

onclick = function(c){return function(){c.doSomething()}}(this);

It's not much more typing, and is more general. I agree arguments would be
nicer if it was a true array though.

~~~
bumblebird
Instead of downmodding, why not explain why you disagree with the facts I
present above?

------
fadmmatt
Don't forget the Y combinator and the memoizing Y combinator:

[http://matt.might.net/articles/implementation-of-
recursive-f...](http://matt.might.net/articles/implementation-of-recursive-
fixed-point-y-combinator-in-javascript-for-memoization/)

------
hendrik
I really like his approach to teaching JS, but I wish he would finally finish
his "Secrets of the JavaScript Ninja" book. If I recall correct, I pre-ordered
this book almost 2 years ago, when it had a release date of a few months
later.

