Recently I gave two talks at the Web 2.0 Expo in New York City and one for the Boston IxDA.
Learning Advanced JavaScript
An advanced talk on the JavaScript language. Explored functions, closures, function prototypes, and inheritance. The entire presentation was given using an interactive site/presentation (tested in Firefox and Safari).
Feel free to browse through the presentation (I’m not sure how useful it will be without me talking about the particulars – but it may be nice).
There are a number of neat things that I like about the implementation of this talk:
- It’s interactive. Each code slide is executable (the user can see the output right away). Additionally each slide is editable – just double-click the code to go into an edit mode.
- Code editing is simple. Basic IDE functions (auto-indentation, proper tabbing, and backspace-to-delete-tab) are included. It’s not a ton but it’s enough to get started.
- All code slides include syntax hilighting.
- All slides are bookmarkable.
The presentation includes a number fill-in-the-blank quizzes to help test your knowledge of what you just learned. In practice I may save this for situations in which more people have laptops/computers at the talk.
You can download the full presentation as a zip file.
Building a Visualization Language
I gave a talk on my work with Processing.js, together with covering how the Canvas element works and the Processing language itself.
During the talk I stepped through the construction of a visualization using Canvas:
jQuery for the Boston IxDA
An introductory presentation explaining how jQuery works.
The meat of the presentation was a series of interactive slides which could be run and played with in order to better understand how jQuery works.
You can download the runnable code as a zip file.
Upcoming
I’m going to be giving a number of talks this weekend at the jQuery Conference followed by The Ajax Experience, I’ll be sure to post the slides and code from them, as well.
Bonus
Last week was the MIT Career Fair – I stopped by and worked the Mozilla booth with Boris, Brad, and Julie – a good time as usual:
Cameron Westland (September 22, 2008 at 7:35 pm)
John, I’d like to see more stuff like this, great idea. Now all we need is for you to make firebug look like this!
Josue R. (September 22, 2008 at 7:47 pm)
Dunno how i would have learned this stuff without your help :D Thanks for the presentations!
Joe (September 22, 2008 at 8:53 pm)
Thank you John for writing something ELSE about the amazing Processing.js port job that you did recently. There isn’t much except demos out there so any tidbit of info is incredibly helpful. Currently debating between using Google’s Data Visualization API or straight Processing.js (w/Canvas) to render realtime financial data. Both?
-Joe
http://www.subprint.com
Kate (September 22, 2008 at 9:32 pm)
Thank you John, awesome demo, presentation and tutorial.
JohnM (September 23, 2008 at 12:43 am)
I really enjoyed the examples in the learning advanced javascript slides. Can anyone recommend a good Javascript book that deals with these type of advanced JS issues in depth?
Arnaud Bailly (September 23, 2008 at 12:52 am)
John, another thank you for another great post ! I wonder if it would be possible to reuse the style of the talk, with due credit of course ?
I shall give myself a talk on javascript and functional programming in a french conference and I really like the idea of an interactive presentation where js got executed on browser.
Senthil Kumar (September 23, 2008 at 1:09 am)
John, Thanks for sharing
Jason (September 23, 2008 at 2:15 am)
Nice one ;)
David (September 23, 2008 at 2:54 am)
Dude, brilliant way to teach and share. I’m blown away. Question, why did you go with Array().slice.call instead of Array.prototype.slice.call ?
Marko Mrdjenovi? (September 23, 2008 at 3:25 am)
I think there’s an error in slide #69 – the swung method should be returning this, not false. The test passes cause undefined evaluates to false…
bipedal (September 23, 2008 at 3:38 am)
Great, thanks for sharing, John !
Tien Dung (September 23, 2008 at 3:49 am)
Advance JavaScript slides are great. Will you cover them (more details) in you next JavaScript book?
Dave (September 23, 2008 at 6:22 am)
This looks great! I’m currently on slide #40 and learning lots.
Is the slide code released under licence? This would be a great format for teaching JS at college.
Could fairly easily be enhanced to run PHP code too, though security would be a big concern.
Markus.Staab (September 23, 2008 at 7:17 am)
shouldn’t it read assert(user.name == “Resig” …) on the first slice?
John Resig (September 23, 2008 at 8:15 am)
@Joe: Honestly, it depends a lot upon your current situation, the data that you’re using – a number of factors. I’m not sure I could say one way or the other.
@JohnM, Tien Dung: All of this is discussed in my upcoming book Secrets of the JavaScript Ninja. I’m still working on it so it probably won’t be ready until late in the year, early next year.
@Arnaud Bailly: Sure thing, go ahead – feel free to re-use the style of the talk.
@David: I did that explicitly because up until that point Function prototypes hadn’t been discussed or explained. I didn’t want to bring them into the picture too early and befuddle the discussion with other concepts. I discuss the benefit of using Array.prototype later on in the slide set.
@Marko Mrdjenovi: Ah, thanks – I had fixed that in a local copy of the presentation that I had but didn’t upload it, I’ll do that now.
@Dave: The slide “software” itself is under an MIT license, the code itself is not – a large part of it is from my upcoming book.
@Markus.Staab: I’m not sure what you’re referring to – I don’t think that would be the case on any slide – can you provide a link to the exact slide?
Jason (September 23, 2008 at 8:34 am)
Question regarding slide #38:
Why isn’t it possible to replace
if ( !(this instanceof arguments.callee) )
return new User(first, last);
with
if ( !(this instanceof arguments.callee) )
return new arguments.callee.apply(this,arguments);
I would have hoped this would allow a fully generic way to force proper construction. Instead, the call fails.
John Resig (September 23, 2008 at 8:48 am)
@Jason: It’s not possible, in JavaScript, to apply arguments in to a call in which you want to “new” (they’ve been looking at fixing this for the next version of JavaScript, we’ll see if that happens). The problem here is two-fold: Doing
arguments.callee.apply(this,arguments)
calls the function like normal (with the arguments applied in) and attempts to return the result – that result has ‘new’ applied to it. Now we never reach that point because doing the above would actually recursively call the function over-and-over again. It’s definitely a sore point in JavaScript.In the original JavaScript 2 proposal you could do:
new arguments.callee(...arguments)
and that would lay the argument values in as if they were normal arguments.Dean Edwards (September 23, 2008 at 9:09 am)
John, have you ever looked at base2’s RegGrp? Your parsing techniques are really similar. Which means they are awesome. ;-)
Dean Edwards (September 23, 2008 at 9:10 am)
Ah, I see the syntax highlighter is written by someone else.
Peter (September 23, 2008 at 12:31 pm)
John, In response to your answer to Jason. Why can’t you do something like this:
Function.prototype.construct = function(args) {
var that = this;
var bare = function() { that.apply(this, args); };
bare.prototype = that.prototype;
return new bare(args);
};
so relplace
if (!(this instanceof arguments.callee))
return new User(first, last);
with:
if (!(this instanceof arguments.callee))
return arguments.callee.construct(arguments);
John Resig (September 23, 2008 at 12:40 pm)
@Dean Edwards: Yeah, RegGrp is real nice – would probably use it (or similar) if I was doing some syntax highlighting fun.
@Peter: Sure you *could* do that – of course that’s significantly more complicated than what I’d like to get in to with the talk. (You need to be sure to update the .constructor property, as well). Note that I did something similar with my Simple JavaScript Inheritance script.
Nano. (September 23, 2008 at 10:44 pm)
Hi John,
Great stuff (as usual). Just wondering, for the interactive learning tool, adding a button that will show the TOC with links to each item will be really helpful!
Thanks,
Nano.
Leons Petrazickis (September 24, 2008 at 9:35 am)
Bug Report for #43 in Firefox 3.01 on WinXP
1. ERROR arguments.sort is not a function
John Resig (September 24, 2008 at 11:48 am)
@Leons Petrazickis: Leon, that’s the point of that slide, it’s supposed to error out like that (which is why it asks a question in the title and fixes it in the next two slides).
Adam (September 24, 2008 at 2:24 pm)
On http://ejohn.org/apps/learn/#27 :
I recommend testing for “i” as an input (test not undefined) — I “passed” the test without passing i in each loop iteration (didn’t pay attention):
fn.call( array, array[i]);
= all PASS
I recommend adding to the test:
assert(i != undefined, “All parameters should be passed in properly as well”);
Awesome stuff!
Adam (September 24, 2008 at 2:28 pm)
On http://ejohn.org/apps/learn/#31 :
If ninja.swingSword() executes twice, then ninja.swing is false — which somewhat undermines the metaphor.
Adam (September 24, 2008 at 4:46 pm)
http://ejohn.org/apps/learn/#69 :
Shouldn’t “swung” be false to start and then true once “swing” occurs? (similar to comment on #31)
danigb (September 24, 2008 at 7:33 pm)
Awesome! Thanks again! I would never understood so much javascript to easily ever!
David M (September 24, 2008 at 8:30 pm)
The Adv. Javascript presentation was awesome!!!! I’d love to see more. Have you thought about setting up an online course? I think I learned more about Javascript in the two hours I spent going through the slides (I do things slowly :-)) than I have in the past year mucking around with tutorials. I think the brilliant thing about it is that it’s not really set up as a traditional tutorial. (where you usually jump to the end, grab the working code, and move on…) The quizzes really help too. Can’t wait for your book!
ricardoe (September 25, 2008 at 1:04 am)
Just WOW!
I’m just at #40 and I’ve learned more than 1 year of js issues self-reading…
I’m won’t be a liar if I call you Master.
Regards from México and keep it up!
Jonathan Fine (September 25, 2008 at 3:56 pm)
I like the slides, and hope to read them through soon. I have a comment on http://ejohn.org/apps/learn/#2, which reads in part
var object = args.shift();
return function(){
return fn.apply(object,
args.concat(Array.prototype.slice.call(arguments)));
Just a few days ago I did something similar (see http://jonathanfine.wordpress.com/2008/09/21/implementing-super-in-javascript/).
There I’m wanting to define a ‘super’ method, and came up with
var sup = function(klass, name){
return function(){
var fn = klass.proto[name];
return Function.call.apply(fn, arguments);
};
};
Your code and mine are doing something a bit different, but if I’ve got things right your code is equivalent to
return function(){
return Function.call.apply(fn,
args.concat(Array.prototype.slice.call(arguments)));
Note that this no longer apply shift to args to obtain object. I suspect that this implementation is slightly quicker. (Of course, your goal was to teach, not to produce the the most optimal code.)
Lars Gunther (September 26, 2008 at 9:57 am)
Hi John
This is Lars Gunther of the Web Standards Project Educational Task Force. I am in charge of developing courses for being used in colleges and universities on DOM Scripting.
This is the most exciting JS teaching resource I’ve seen. Period. I intend to re-use it and recommend it being used literally all over the world as part of our Curriculum Framework: http://www.webstandards.org/2008/07/31/announcing-the-wasp-curriculum-framework/
Could we get in touch with each other on this matter? (You have got access to my mail from this comment, right?)
Kevin Hakanson (September 26, 2008 at 9:56 pm)
Cool stuff! What do you think about an example like this in the Inheritance section? It was an issue that got me once because I didn’t realize that the two Ninja instances shared the one instance of the victimNames array. Feel free to modify as you wish.
function Ninja(){}
Ninja.prototype = {
victimCount : 0,
victimNames : []
};
Ninja.prototype.victimize = function(name) {
this.victimCount++;
this.victimNames.push(name);
};
var ninjaA = new Ninja();
var ninjaB = new Ninja();
ninjaA.victimize("A1");
ninjaA.victimize("A2");
ninjaB.victimize("B1");
assert(ninjaA.victimCount === 2, "ninjaA victim count should be 2" );
assert(ninjaB.victimCount === 1, "ninjaB victim count should be 1" );
assert(ninjaA.victimNames.length === 2, "ninjaA victim names length should be 2" );
assert(ninjaB.victimNames.length === 1, "ninjaB victim names length should be 1" );
Jose Noheda (September 27, 2008 at 6:30 am)
That last line in the last slide was just mean :-)
frio80 (September 28, 2008 at 4:53 pm)
In slide 13, if you made the following changes to yell, the object is not destroyed. I’d like to know why. Thanks in advance.
var ninja = {
yell: function(n){
return n > 0 ? this.yell(n-1) + "a" : "hiy";
}
};
assert( ninja.yell(4) == "hiyaaaa", "A single object isn't too bad, either." );
var samurai = { yell: ninja.yell };
var ninja = null;
try {
samurai.yell(4);
} catch(e){
assert( false, "Uh, this isn't good! Where'd ninja.yell go?" );
}
frio80 (September 28, 2008 at 6:35 pm)
Ah, I see why now. Should have finished the tutorial first.
szimek (September 30, 2008 at 4:35 pm)
This Advanced JavaScript tut is really great! Thanks a lot!
Two questions:
– what’s the difference between
Array().slice.call(arguments)
and
Array.prototype.slice.call(arguments)
?
– I don’t really get the whole point of converting “arguments” into an Array and why the code on slide #43 actually fails. What does it mean that “arguments” is an “array-like object”? What’s the difference between it and a “pure” array object?
Breton (September 30, 2008 at 8:21 pm)
@szimek
“- what’s the difference between
Array().slice.call(arguments)
and
Array.prototype.slice.call(arguments)
?”
functionally, they both accomplish exactly the same thing, they just take a different path. The first one, you’re creating a new “Array” object, and looking up the slice method on it. Since the new array object doesn’t have a slice method, javascript automatically defers to the Array.prototype object to find it. Then once it’s found, it looks up the call method on the slice method, and binds arguments to “this” for the slice method- So it ends up being like calling slice on the arguments object, as though it were an array.
the second one, instead, skips a couple of steps. It does not create a new instance of an Array object, instead it goes directly to Array.prototype and looks up the slice method there. The rest is exactly the same.
“I don’t really get the whole point of converting “arguments” into an Array and why the code on slide #43 actually fails. What does it mean that “arguments” is an “array-like object”? What’s the difference between it and a “pure” array object? ”
It’s a misnomer to call it a “pure” array object, because it’s actually rather dirty. The main difference between arguments and array, is that the prototype of arguments is “Object”, and not “Array”, therefore it does not have any of the array methods, such as “slice”, or “push” or “pop”, etc. There’s between 10-15 really useful functions on the array prototype that arguments doesn’t have. If you want to use them on an arguments object, you have to jump through all the hoops outlined above with the “call” function.
It’s an array-like object, in that it’s an object which stores its members in properties that are integers, and it has a length property. Similarly, jQuery() returns an array like object. The html elements it contains are stored in properties that are integers, and it has a length property, so you can do many things with it that look like the things you do with an array. However, it is not an array, because its prototype isn’t Array.
Breton (September 30, 2008 at 8:39 pm)
and of course, the code on slide #43 fails because the arguments object doesn’t have a sort, or a slice method on it, and it doesn’t have Array.prototype to automatically fall back on, since its prototype is Object instead.
szimek (October 2, 2008 at 2:25 pm)
Thanks a lot for the explanation.
I was mislead by:
log(arguments.constructor); => LOG function Array() { [native code] }
Need to read more about prototypes/constructors in js.
Edu Felipe (November 5, 2008 at 9:48 am)
Loved the tutorial. Used internally in my company as a head start for our advanced javascript training.
One thing I noticed, in your last part, the pun on Alex Russell not being a JavaScript Ninja was very subtle, hehehe.
Three thumbs up for your new book! (Yep, with and extra thumb)
Timothy (November 20, 2008 at 11:28 am)
The ‘Learning Advanced JavaScript’ had some really, really useful topics. Most I knew, but there was enough that the entire presentation was enjoyable. I would highly recommend reading through it. It’s not too long.
Timothy (November 20, 2008 at 11:30 am)
Oh, and, @John
What the deal with Object.prototype.___ and Element.prototype.___ in IE(6)? It won’t let me access / implement prototypes for these native objects. I understand that Object.prototype is not safe (since it will add in extra values in a for()) but I was attempting to write my own Element.prototype.remove() and IE freaked out.
-Tim
Ariel Monaco (February 21, 2009 at 10:36 pm)
I give you five ninja stars for this excellent tutorial :)