Google I/O 2011: Learning to Love JavaScript

Google I/O 2011: Learning to Love JavaScript


Russell:
Good afternoon. I’m Alex Russell. I’m a software engineer
on the Chrome Team. Thanks for tearing yourself
away from lunch to come hear
about JavaScript. So like I said, I’m an engineer
on the Chrome Team, and before I joined Google, I spent a lot of my life
working in JavaScript. I joined the Chrome Team from
a web development background, specifically working on open
source JavaScript tool kits and before that, working web application
development and security. And before my recent
detour into C++, I spent most of my day
trying to figure out how to make JavaScript
do interesting things. My personal history with
JavaScript started in 1997, I think when a lot of us started
to be cognizant of the web. And at the time, JavaScript
was this thing that was starting
to become powerful and somewhat standardized and somewhat widely available on
the back of the browser wars. So I want to talk a lot about how we got to where we are
today with JavaScript, why it’s so important,
why that history, that long history continues to figure into the sorts of
things we try to do with JavaScript on
a day-to-day basis. And I want to take you
through what’s really inside of JavaScript. What is it about
JavaScript that it is, that makes it so different
to the languages that you might be using
in your day-to-day work that aren’t JavaScript,
because there’s a lot that is. Exactly where
are we right now? Because I think
this is also sort of an ambiguous question, right?
If you’re a browser bender, it’s easy to say
we’re this fast–easy-ish. If you’re a web developer, you can look
in your deployed base and understand
who’s got what, but that doesn’t necessarily
tell you anything about the future. And I want to spend a lot
of time today talking about how it is that we are going
to get a different future for JavaScript, because JavaScript,
like the browsers, is starting to move again, and I want to
tear back the veil that covers each of
these topics and help you understand
exactly what’s going on and how these parts relate to
each other, because they do. The history informs
the future, and the current state informs
what’s going to happen next. So JavaScript is
a functional language. So how many of you write
in other functional languages or are familiar with
functional languages? Awesome. The front of this talk is
going to be something that maybe just warms your heart
and may not be new information. So JavaScript is
a functional language. In the sort of the history
of functional languages, it supports closures. Much like Scheme, it’s got this nice
first class function system, and in 1995, Brenda and I hacked
it up as a little prototype which made its way
into Netscape 2, and Netscape 2
was the first browser to really have any serious
scripting supported. It had DOM level 0,
and soon afterwards, JavaScript sort of, you know, once it escaped
into the browser, started the standards
process at ECMA, not inside the W3C, because the W3C wasn’t
the place for languages. And in 1997, we got
the first version of JavaScript as a standard. In 1996, Microsoft
shipped IE 3.0, and that was the first version
of JScript. So we now had two competing, mostly compatible
implementations of a scripting language
for the web. Nobody knew how big
the web was going to be, although, at the time, it looked like things
were trending up. Well, we know how
that story ends. Today, you can’t ship
a credible platform that doesn’t have the web. In 1999, ECMAScript
version 3 was finalized at TC39,
which is the technical committee that is the standards body
for JavaScript. And from its humble roots as Mocha/LiveScript/JavaScript
in Netscape 2, JavaScript 3, ECMAScript 262-3,
the version or the standard that was released in 1999 has
powered us pretty much to today. It has been the thing
that for more than a decade has been what
we think of as JavaScript. And JavaScript, on the back
of that standard, has gone pretty much everywhere. JScript, the component that runs
JavaScript inside of IE, has been built in to the OS
for Windows since Windows 98. You can’t get
a copy of Windows, you can’t buy
a copy of Windows today that does not include
JavaScript in the OS, and every browser on the planet
now includes at least one implementation of
JavaScript, and these things are moving
really, really fast. I work on the Chrome Team;
therefore, I’m partial to V8. It goes nice and quickly, but these things
are all compatible to a very high degree. All of these implementations
are separate implementations, and they’re competing
on things that aren’t, “Oh, here’s a new language
feature.” We’re collaborating
on language features in the standards committee, but we’re competing
on performance, which is a really great place
to be for a language, because it takes
a lot of investment to make a language
a real success. It takes
a lot of deployment, a lot of competition,
and a lot of investment to sort of get
the really smart guys that it takes to go make
a VM go like hell. And so JavaScript has been
the beneficiary of this sort of ecosystem of
investment in a way that only a couple of languages
before it ever have. And as a result, today’s
JavaScript runtimes and today’s JavaScript
performance are vastly different than they have been in the past,
even the recent past. And so every device
that you get today, including the tablets that were
handed out to you yesterday and the Chrome books that you’ll
be receiving as attendees on June 15th, these all have JavaScript as
a core part of their runtimes because the web
is the platform. The web is the way
that you’re going to build a lot of the applications that your user
is going to care about, and it’s the way to build
portably today. So JavaScript is everywhere,
and it’s terribly misunderstood. And I think what I want to do
first here is to talk you
through the parts that most people don’t
really have a sense of, when they talk about, like, what is it that makes
JavaScript different? Because we hear it’s
a dynamic language. We hear it’s
a functional language. But it looks a lot like C.
It looks a lot like Java. It looks a lot like C++. And some folks have been
doing a great job in the last couple of years at
sort of helping to tear back the blinders
that are on us, as folks who come from
a C or C++ background, and help lay out what it is. But I want to go
through it very briefly, because I think it’s
important to understand what’s actually in there, because when we understand
what’s actually in there, we’ll understand how
the language can evolve, because you don’t want
necessarily separate– competing ideas to be existing
inside the same language. You want a language to sort of
have a theory of itself. You want it to be coherent
in ways that make it, so that when you understand
one part of the language, you can understand
the next part of it. And my interest in this is
coming from a background as a web developer, I serve as one of Google’s
representatives to TC39, the standards committee
for JavaScript. And so I have a particular
and keen interest in making sure that we evolve
the language in ways that are reasonable
and solve real world problems that we’ve all got. So JavaScript only has
a couple of key languages. I said earlier that JavaScript
is a little functional language, and JavaScript started out as
a very small language entity. There aren’t a lot
of core concepts. There’s no type
system, per se. There are types. You can have a number,
or an object, or an array, but there’s no
type testing. There’s no way to define
your own types, necessarily, and have them participate at,
like, function call time and have the system throw
an exception for you, unless you do the testing
yourself. And JavaScript
reads top to bottom. JavaScript has
run-to-completion semantics. That means that if you
start a body of code, there’s no multithreading
in the language. There’s no way for you to sort
of fork off some other process. Anything that does that in
a JavaScript environment is doing it as a built-on. So browsers with their set
timeout and their set interval. That’s all happening outside
of the core language semantics. JavaScript reads
top to bottom, and the interpreter
and runtimes read it exactly and run it exactly that way. If you see a block of
JavaScript code, it goes from top to bottom,
and that’ll become important, as we see in
just a minute. Almost everything in
JavaScript is mutable. That means that you can
change nearly everything, and we’ll talk about the
several exemptions to this rule, but those exemptions
are very small, and they’re very narrow,
but they wind up being powerful. So that means that if you
get an object back from some function call, you can probably change it
in JavaScript. Closure is the way we do
private state, though, so if I get an object, and everything is mutable, it means, ah, I might be able
to surprise somebody else. I might be able to go
change some state out from underneath them. The thing that returned me
the object might expect it back in some
reasonably okay state. Well, the way we do data
hiding in JavaScript isn’t through the private key
order, through some method that gives
you some sort of a private field that you can only see. Instead, we invert
the relationship between classes and functions, and we treat functions as
behavior that can carry data, versus classes, which are data that can
carry behavior. And so the last key concept is,
instead of having a class, as you understand it in
other languages, we have prototypes, which is to say we don’t have
this strong “is a” relationship through a hierarchy
of classes. Instead, we say,
when I don’t find it here, please look over there. It’s delegation, and
it’s a one-link chain delegation up to a root object
that everybody shares. So we’ll talk a lot about
how exactly all this works, how it fits together, and hopefully you’ll
understand at the end how it’s going to inform
where we can go from here. I said earlier that
JavaScript runs top to bottom. That means if I see
a piece of code in JavaScript, one line before the next, before the next–because there
isn’t necessarily a compile cycle. Most JavaScript runtimes
traditionally were interpreters. That means that the easiest way to think about your
JavaScript program is as something that is going
to happen in a live environment. So if you had
a command line, and you started typing in
commands, JavaScript runs almost
exactly the same way. Top to bottom,
line for line, it gets evaluated in the order
that it is written out in the program,
more or less. And so
statement to statement, your programs–they can change
in ways that are surprising in other languages. Where you might otherwise
have compile time exceptions, JavaScript just sort of
merrily goes on and runs the next line. So whenever we read
some JavaScript code, it’s important to think about
it simply as running at the top and going to the bottom. It’s not really
some big magical machine that’s going to be out there
doing something for you, and then it’s going to start
running your program. It’s just running
top to bottom. So when you evaluate
JavaScript code, and you’re trying to figure
out what’s going on, remember that the line
before it may be the thing that caused the problem. And JavaScript is functional
and object-based. It’s really important
to think of functions as first class in JavaScript. That means that they’re
not simply a pointer out in the world that you
invoke against something. They are actual objects. I’m going to refer to them
through this talk as function objects, because function objects are
indeed objects that you can go and hang behavior off of. But you don’t hang behavior
off of them by extending their public
API area. You don’t say,
“I’ve got a function object. I’m going to add
some new property to it.” Most of the time, you do that
by using functions as scopes. The only way to create
a new scope in JavaScript is to invoke a function. When you invoke a function,
it sort of creates a new scope. If statements, while statements,
for-in statements– those things
don’t create scopes. Only functions do,
so we have this problem of how do we do beta hiding? Well, these scopes
are really smart, because these scopes
hold on to the variables that have been defined
above them in another scope. So what we’ve got here is
a function called get counter, and get counter defines
a local variable, I, and it returns
another function, and that function references
the variable I inside of it. In other languages
like C++ or Java, you really can’t do
anything here, because that variable I
is going to go out of scope in the return function. We’re allocating
a new function here, but that inner function is
going to hold on to I. It actually allocates private
memory to store a reference to I on the function object that’s returned out of
this statement here. It, again, inverts
the relationship. It’s not storage
with behavior. It’s behavior
that has hidden storage. And so the way we do
private variables and the way we do
data hiding in JavaScript is to use this idea of a
closure, something that encloses its lexical scope and holds on to variables as a way
of passing behavior around. So we can call
the get counter function. It hands us back
a function object. We can call it multiple times,
and that state isn’t gone. We can still see the variable I
from inside the outside one, but it isn’t referenceable. We can’t go and inspect some
property on that function object and find out which variables
it’s holding references to. It gets GC’d just like
everything else in the language. So these are
first class functions. These are functions
that are things in the system. They’re actually objects.
You can create them. You can add properties to them.
It can enclose scope. They’re not simply inert
bodies of code that get run. They’re participants
in the object model. They’re participants
in the storage system. You can use them–I know
the fundamental concept that underpins
a lot of the patterns that we’re going to see later. So these functions
work together with a lot of other
sort of functional ideas about how a program language
can be structured. In JavaScript, we have a filter,
map, reduce, and for each method
on the array prototype, which means that every array
in the system has these methods, which means that instead
of having an external iterator, you have
an internal iterator. You have something
that can call a function across some set of arguments, and so you wind up
creating a stack of stuff that you’d like to do
in terms of behavior. Instead of passing
data structures around and around and around, you pass
in arguments to functions, and that sort of
unwinds the thing that you were
trying to get done. You express
your program’s intent in the form of
nested functions that are going to
unwind to some result, not linear code
that’s going to be executed by passing in
the same data structures over and over
and over again. So these sorts of things
are not hard and fast rules about any programming
language. Like, you can have
an endless debate about what makes something a
functional programming language. Can it have side effects? Can it not have side effects?
You know– How completely does it
support some particular set of macro languages,
or hygienic macros, or whatever it is? Many people define functional
languages differently, but for the intents
and purposes here, we’re just going to say
it has closures, first class functions, and some concept of
using those sorts of things to compose behavior
nicely together. So another important thing
to remember about JavaScript is that everything
is just an object. So there aren’t a lot of
key concepts in JavaScript, and so you can think of it as
sort of a lazy language design. It doesn’t really have
a lot of specialized, compartmentalized things to hold on
to different concepts that you might encounter. Instead, it just relies
on the same systems over and over again. One of those systems
is this small type system, where objects are objects,
that first object literal there. It’s an instance of object.
Arrays are objects, which means that arrays are
instances of objects, too. And functions
are also objects. In this case,
I’ve got a paren here, which is going to create
a new expression. I’ve got a function,
which I define inside of here. It doesn’t have a name.
It’s an anonymous function. You can have anonymous
functions in JavaScript. And the result
of this expression is just going to be
that function object. And the function object also is
an instance of the object type, which means that nearly
everything in the system that you encounter
is going to be an object. This is really powerful,
because it means, as we’ll see later, when we compose things,
and everything is mutable, we can start
to change the behavior of large parts of the system
all at once. And every object in the system
acts more or less like a map. There’s no separate
map type in JavaScript. So if you want a map,
just take an object. This is where–
sort of where JSON comes from, this object literal syntax
that we’ve got here, where we’re
defining an object with a single property
and a single value. It allows us to de-reference
properties the same way. So the data operator does
almost exactly the same thing as this map operator. It just finds a property
by its name and returns it out
the other side. So in JavaScript,
everything is an object. Objects operate like maps.
That’s pretty cool. Arrays do exactly
the same thing. And arrays are very confusing
when you start out working in JavaScript, because you think array
is some separate thing over on the side.
Arrays are not objects. Arrays are this linear bag
of memory that you’re going to access
with an integer someplace. And as a result of that, you’re not going to be surprised
by some other identity. But you are, because
very often what happens is you go and extend an object.
You add a new property to it. In this case, we’re going to add
this other greeting property to an object dynamically, and–
or to an array dynamically. And as a result,
when we go into a for-in loop, this is now an innumerable
property on this array. We might get surprised, because
we see these other things showing up in our object. Well, that’s weird. I mean, we iterated
over the public properties. Isn’t 0 just
an integer index thing? It’s not a public
property, right? Well, remember that
everything in JavaScript just sort of falls back
on these core concepts. And if you think about
the array integer indexing working exactly the same way
that property indexing does, it all makes sense. Yeah,
in the implementation, there might be some special
machinery to make arrays efficient
or to pack them tightly, so that you don’t wind up
slowing things down unnecessarily. But in the language semantics, what happens here
when I say, “Please give me item 0
out of this list,” is that it turns
that 0 into a string, and then does a map lookup. That’s all it does. So the only magical thing
about arrays versus any other kind of object
in the system is that,
when I push onto an array or I set the length property, it actually affects
which properties are visible. The length property is
the only thing in an array that’s actually magic. It has a little bit of syntax
for defining arrays naturally; but other than that,
arrays are just objects. Things get turned into strings
and then de-referenced that way. The spec is pretty clear
about this. So JavaScript doesn’t have
that many core concepts. And if you understand them,
you can understand what’s going on
in your system. So we’ve got mutable objects.
We’ve got closures, which are behavior
that carries data and not data
that carries behavior. We’ve got mutable objects, and we’ve got everything
being an object and everything being an object
also being a map. Okay, that’s not a lot
of concepts, so far, for a programming language. And we can use these to build
some really powerful stuff. So I mentioned mutability, and I said
everything is mutable. Just a really quick example,
we can add new properties at runtime to every object. Remember how I said that
JavaScript runs top to bottom? When you’re reading
a program like this, it’s not like my object type
somehow was extended and, therefore, every object
of this type is going to have one of these properties. I’m just adding a new property
to the object directly. So in this case,
object.item is being replaced, and object.item2
is simply being added. These are exactly
the same operations, as far as JavaScript
is concerned. The dot operator
just finds you the object and then assigns to it.
That’s all it’s doing. Every object in the system
is extensible. Most of them are mutable. Most of the values are mutable,
and we run top to bottom. So that means
that when I come down here, and I delete a property
off of the object, the very next line
isn’t going to see it. But if I had said
console.log(obj.item) one line above,
it would see it there. This is not
a compile time thing. It’s just doing what you said,
line after line, statement after statement,
expression after expression. It seems really simple. It seems pretty obvious, but
very few programming languages that you might be using
in a compiled environment work this way. So I mentioned that closures
are the other side of classes, whereas classes
are sort of a nice way of saying,
“Here’s a structure of data. “I’m going to associate
some properties with them, and maybe they’ll have
some type behavior as well.” In this case,
we’re going to create something that we would call a class
in JavaScript. We know it’s a class, because it’s got
an uppercase B for the name. This is not a language
enforced semantic. JavaScript doesn’t necessarily
have classes today. This is just a convention.
And as we’ll see, conventions figure large in day-to-day
JavaScript programming. So remember
every object is mutable. So we’re going to create
down here, we’re going to create a new
instance of our behavior class. We’re going to extend
the local object, this dot, with the variable that
was passed in the configuration, and then we’re going to
extend the object again with a function called do it. In this case, when I call the do it method
of my behavior instance, it’s then going to
run through, and it’s going to say
this.config and go grab some flag
off the configuration. Okay, so we stored some property
and some behavior on the object. This looks a lot like
what you might expect out of another
object-oriented language. The declaration syntax
is a little bit funky, but you sort of
understand it, right? I’ve added a method.
I’ve added some data. The data operates on
the local objects method. Sweet–
or other way around. Strike that, reverse it. New behavior, passing a flag,
then I call it false. I get a behavior object, and now I can call a method
that uses that behavior, right? So it’s going to look
at the local object, this, for the configuration,
and it may change its behavior based on that configuration by
passing some other value to it. Make sense?
Cool? All right. So this is maybe a little bit
more idiomatic for JavaScript. It’s the flip side of that. Instead of creating a class
that I created an instance of, I’m going to
create a generator that’s going to pass me
back a function object, which is going to hold
on to the state. I’m not going to go
create a class for it. I’m going to create
a behavior generator. You can think of them
doing the same thing, just the flip side of it. So instead of saying
new behavior, I’m going to say
bind me a behavior, which when I call this, note the lack of
the new keyword here, I’m going to pass
into configuration. Like we saw earlier, I’m going to pass back out
a function object. This is a new
function object. Every time I call this method,
bind behavior, it’s going to pass me back out
a new function object. So I’m actually having a new
function object allocated here, and that function object
is going to have, again, some private storage,
and that private storage is going to hold on to
the config variable that was passed into
the outer function, right? Because each one of these
is a new scope, and because scopes
can hold on to the variables that they were able to see
when they were defined, the function object
that gets passed out of here now has a reference. It’s holding on to
that local state. In this case, it’s going to be
the object that was passed in. This might go out of scope here
in every other place in my program. I may not be able to get
a reference back to this object, but my behavior, the B variable
that was passed back out, will have access to that data because it’s being held on to
internally. It’s not going to be
garbage collected out from underneath me. Closures are the way to invert
the way you think about your programs. You don’t create classes
that are state with data, state with behavior attached. You create behavior that holds
on to the state that it needs, and you can pass
that behavior around, because functions
are first class. So I mentioned earlier that
the last sort of big conceit in the language is that we
don’t have a way of saying, hey, here’s a class of stuff. Instead we say,
if you don’t find it here, don’t look at my like
chain of class inheritance. Instead, just go look
at that other object. Remember how I said
over and over again that JavaScript
just reads top to bottom? I get some code. The thing executes
front to back, top to bottom. We’re going to see
the exact same thing here, because what happens every time
you call the .operator is exactly the same thing. I’m going to create
some variable that I’m going
to call my delegate. It’s an object.
It’s got a single property. Okay, cool. There’s a new ECMAScript 5
method called object.create. There’s other ways to do this
in older versions, but they’re a little bit
mind bending, and we won’t go over them. But object.create–
the easiest way to think of it is that it creates a new object
which will look at the object that you pass
as its first property if you don’t find a value
with this same property name on that object. So let’s say–and in this case,
I’m going to create object 2 and have my delegate
be the delegate. And so when I reference
a property out of object 2, it’s going to go look it
up dynamically, and if it doesn’t find it
on object 2 directly, it’s going to go look it up
off of the delegated 2 object. It’s going to go,
dynamically go and try and find it
over there. Well, we created
another object. In this case, we’re setting
a local property on that object, whose name is item,
whose value is value. And that means that
when I look it up at runtime directly top to bottom,
left to right, what I see is that
I don’t get the value that was set on my delegate. I get the value that was
on the local object. The .operator doesn’t fail
on the local lookup. It finds it on
the local object. And instead of looking up
the chain, it says, ah, I’ll just give you this
object’s value right back. So JavaScript is
incredibly dynamic when it comes even to looking up
properties on objects. There’s not some fixed list
of stuff that you can do. You can change
the delegation, and you can change
the properties that are available
on every object that you’re delegating to,
or your local object, and that changes what happens
when you go and look stuff up
at the very next line. So in this case, if I go and I change the value
on the delegate, I change the item value
on the delegate, remember that object 2
doesn’t have a local property called item. If I fail on that lookup
on object 2, it just goes and says, ah, okay,
let’s go consult my delegate, and that delegate is now
going to have the new value. So the new value has
been shadowed all the way through to everything else
in the system that is delegating
to that object. This is incredibly
powerful. The dynamic nature of
JavaScript means that because it reads
top to bottom, because almost everything
is mutable, and because I can delegate
to most other objects when I create something, I wind up in a place where
I can create brand-new behavior at runtime. I can compose things on the next
line that didn’t exist before, or I can change
the behavior of other objects in the system, based on what
they’re delegating to. This turns out to be
a great way to go build up
a lot of the constructs that we get in other languages
for ourselves, because JavaScript may not
give them to us naturally. This power is the sort of thing
that really drew me to JavaScript
as a young programmer. I didn’t really understand
what I was dealing with. I remember I had a friend
who told me, after I’d written some article
about how to do signals and slots,
some sort of aspect-oriented event style thing,
he’s like, “Well, why didn’t you just use
a closure for that?” And it took me a long time, probably six months
or more after that, to sort of really understand
what it was that he meant when he said,
“Just use a closure for that.” I didn’t understand
that you could hide data inside of functions. I didn’t understand
that JavaScript sort of ran top to bottom. But these core concepts
allow you to create all sorts of
really powerful stuff, assuming we understand what
happens with the word “this.” So the word this
is really special. In order–Because we don’t have
classes that wire up this inheritance hierarchy, and because we’re always
delegating at runtime, right, every .operator sort of
does the dynamic lookup on the local object– looks at its delegate,
looks at its delegates. The this object
is a way of saying, okay, whatever scope I’m in, execute the next lookup
against the local object, which means that the this
keyword in any function isn’t pointing
at some fixed object. It’s not fixed
when I necessarily say, you know, create me an object.
It’s promiscuous. The this keyword points
at whatever object my function is being called through. Right, remember function
objects are first class? They don’t actually sort of
carry around relationships to their class or the thing
that they were defined in. They hold their own data. So the this keyword is
a nice little syntactic out which lets you say, okay,
whenever I look up a property, which happens to be
a function, and I call it, the .operator
for method calls says don’t just return it. But if I evaluate it directly,
use the .call property of the function object that’s returned and call it
in the scope of the object on the left hand side
of the .operator. I know this is a little bit
maybe tricky, but the easiest way to think
about this is that in order to wire up this behavior
correctly, so that it sort of does what you
expect out of other languages, we rely on the function
being first class, meaning it has its own call
and apply methods. You don’t say necessarily,
hey, function, you’re not going to work
if you’re not called inside of some other object. I can call any function in
the scope of any other object. I can assign a function to any
other object and then call it through that object
dynamically, right? Everything is mutable. Functions are first class.
Why not? So in order to get
that to execute against the right object, you use the this keyword
to go grab the value out of the thing that was on
the left hand side of dot, which is exactly
the same thing as saying please call my function, which I pulled
out of that object, in the scope of the object
on the left hand side. Cool? All right. Okay. So all this fits together
in ways that allow us to recreate a lot of this stuff
that we expected in other languages. A lot of this
is convention. A lot of this isn’t necessarily
the sort of thing that you’re going
to have language level or syntactic support for, but if you understand
what’s going on there, those sort of core little ideas
about mutability, scope, functions as first class
citizens, and dynamic behavior, we can start to recreate
things like classes. So here we’ve got an item type, which is we’re going to
think of as a class. It’s not really
called a class. It’s just a function.
It’s got the word function. As you saw earlier, when you use the word new
in front of any function, it sort of creates an object, calls that function inside
the context of that object, and then returns
that object back to you. That’s the way to think
about the new keyword. So we’re just going to
create a function, which we’re going to call
with new sometime later, and inside of it
we’re going to execute a couple of other functions. Now, we just saw .call,
and .call calls those other functions
in the scope of the object that we’re being executed in
or that we want to pass in. In this case, we’re going to
pass in the local object, and we’re going
to do it twice, which means that
inside of tract, we’re going to assign
a new property to this– which is to say the object
that was passed in– and inside of logged, we’re
going to assign a new method where that method is going to go
dynamically look up the ID and log it out. So we call these mix-ins. These two methods up here
were written in a way that they don’t delegate
to anything else. They don’t assume anything about
the behavior of their methods or the properties
that they define. And instead,
they just add stuff. They just add stuff
dynamically when they’re invoked against
some other object. So I could call them
in any other context, but in this case, I can use them
in the item type constructor to extend the item type
with some new stuff. We saw earlier how
delegation allows you to create new delegate
relationships between things, and functions also have
this idea of a prototype. This is the exposed version
of the thing we saw before with object.create, where I can say,
please wire up this relationship so that this object,
when you don’t find it here, looks at that thing over there. So if we create
a new item type, what we’ll see is
that it has an ID, and it has a type associated
with property added to them, which is pretty good.
And if we create another one, the counter is incremented, and the type is still
assigned to the same value. But if we create
a new sub item type, what we see is that,
because the prototype created a new property called type
with a new value, again, the delegate system
faults on the local object, looks at the object’s
prototype–in this case, SubItemType.prototype–
pulls it out of there and doesn’t fault all the way
through to ItemType.prototype. So we can compose
these things together in a way that gives us something like
classical inheritance. It’s not exactly
the same thing. All this is dynamic. I can go and change
these prototypes. I can change
these objects later. But I’ve got the ability
to factor out code into something like a macro
or a trait, using mix-ins, and I’ve got the ability
to create an entire subclass
relationship, where I define
new function types which defer
to their super classes for a lot of their behavior. All right, we’re starting
to get someplace. These core concepts have
given us the ability to define things that the language
didn’t give us naturally, but we can go get
for ourselves. You know how I said
that everything is mutable, more or less? That means that we can
go and extend the stuff that is deferred to
by almost every object in the system, right? Remember, arrays
are objects. Objects are objects.
Functions are objects. Well, those things
have prototypes, too. They have exposed objects, which are–they defer to
when you don’t find a property in the local object. So a radar prototype is, again,
an object which is mutable, and every instance of array,
every array in the system that faults on some property
is going to go look it up off of this object instead.
So I can extend it. I can say array.prototype.clear
is a new function. I can extend every single
array in the system at runtime, because the next line
is going to look it up through exactly
the same mechanism as everything else, right? This is not me
changing the type of array. I’m just extending
it dynamically. I’m creating a new thing
for you to hit, when you don’t find the property
in the local array object. And I’m going to add to. In this case, they’re
going to return new arrays when they’re done, and so
I can chain them together. And so this is how
you can sort of create little dynamic languages
in JavaScript. You can create DSLs
in JavaScript by changing the things
that you delegate to. If you create new objects, and they delegate
to some prototype, and you can mutate
that prototype, well, then you can change almost
everything about the system. Yes, you can change almost
everything about the system. And, yes, it is a huge
maintainability nightmare. This is really good
when your code can do it. This can be a huge problem
when everybody’s code can do it, especially as you get
into larger code bases. So collectively,
as a community, the JavaScript world has started
to learn these patterns of practice, which they say,
please don’t ever go and mutate array.prototype. Please don’t change
object.prototype, so that you don’t wind up stepping on somebody
else’s toes, stepping on somebody
else’s extensions. But this is power
that we’d really like to have. This is power that
we’d really like to be able to take advantage of. Being able to extend
methods in the system is the sort of thing that we’ve seen work pretty well
in languages like C#, where they have extension
methods to interfaces. We really want to be able
to use this, because it shortens up our code. It makes it dynamic.
It makes it easy to read, and it makes it possible
to build up the language to meet us halfway, which is a great feature
of many dynamic languages. So JavaScript has this
incredible dynamic behavior, which gives us
a lot of power, and so we wind up using it
to do all sorts of things that the language
doesn’t necessarily, because it’s a little language,
have built-in support for. So in this case,
I’m going to, again, create an expression
that has an anonymous function defined inside of it. But, instead,
I’m going to do some stuff here where I’m going to define
a local object, right? We’ve seen this before, that might get captured
in an enclosure; and, in fact,
it’s going to here. But the little piece
of sophistry at the bottom there, or in the middle there,
where I end the function, I end the expression, which is going to return
that function as the result of
that expression, and then I invoke it
immediately, means that what happens here is that I’ve sort of
created some code and just run it directly. I’ve just top to bottom run some code, which is going to
define a local variable, create a function–
which is not local, which is going to get exported
back out to the global scope, but that function can see
the local stuff, right? So I can sort of hide away
in my own private stuff inside of my module
by putting it in this pattern, using VAR for the stuff. It’s a local and emitting VAR
for the stuff that’s global. That’s pretty good. We’ve got some sense
of modularity, again, built on this few set of
prototypical properties of the language: mutability, functions
as first class and functions as the only things
that create scope, the ability to modify
nearly everything, and closures as a way
to bind behavior to data and not the other way around.
Okay, so as you can imagine, we’ve seen a couple
of places here now with classes
and now with modules, where we could start to use
these patterns together to start to build up
our little library of stuff to help us
meet the challenges that we’ve got in
the large code base; and, in fact,
nearly every large code base has a library like this. The world of
JavaScript libraries has a lot of different answers
to a lot of the questions that you want.
So for modularity, it’d be great if we could
sort of have a script loader that would pull in
a bunch of stuff. It would transitive
dependency management, and it would put our stuff
inside of this body of code that we could then
think of as something that has dependencies
but can also hide local state. So this is the closure example. This is the tree control,
and these are its dependencies. And it does almost
exactly this, right? This is the module
that it might define, and it’s going to
export some stuff. Okay, that’s pretty good. But then you look at
other JavaScript libraries, and they do almost exactly
the same thing. Here’s a tree control
from the tool kit that I used to work on, digit. And so that does exactly
the same thing, right? We’ve got this
module pattern here, where that’s going to be
what you define inside of it. And at the same time,
these two syntaxes and these two semantics
aren’t interoperable. You can’t use them together.
That’s not great. Now, we’re in a place where
we have all of this raw power, and we can start to harness it
in ways that solve our problems, but we can’t say the same thing
unless we all agree a priori which sort of patterns
we’re going to use and in which style
we’re going to use them. So this is the role
of the language. This is where language
evolution can really start to pay off
some big dividends. And so this is Dave Herman’s
simple module proposal syntax, and this is something
like the array, the tree control requirements
written out in the new syntax. As you can see,
we actually have syntax saying this thing
is going to be a module. I’d like you
to acquire it. I’d like you to import
these sets of things into my local scope. And because we’ve got syntax
for this in harmony, which is the next version
of ECMAScript, we’ve got the ability
for everyone to agree on what it is
you’re trying to get done. Because you have syntax, no one now has the incentive
to go write their own thing. You can start to rely on
there being one canonical way of saying here are my exports,
here are my imports. Here’s how it’s done. And so tool kits can
start to interoperate. They don’t have to
continue to compete or, you know, reinvent on the basis of
a low level set of things that you might hope
would be provided for you in the language. The same thing
goes for classes. You know how we saw
all that boilerplate earlier, where you had the mix-ins
were for functions, and the classes which were
defined as functions– well, they all have
the same word, function. How do you know
it’s a function? Again, we saw the word function
reused to go define that closure, which gave us the scope
for using the module pattern. Well, the word function
gets a lot of use, and in fact,
it is used so often that it’s hard
to understand exactly what it is
you’re reading sometimes, if you’re not familiar
with all of these patterns. And so nearly every tool kit
comes along and creates a shorthand
to help you define a class, because, you know, you can just write
a function that’ll do it. Closure does it. Prototype does it. You can imagine
that MochiKit or Dojo all do it slightly
differently, and these all lead to slightly
different semantics, because the way that you wire up
those relationships internally– and I showed you one way
with using traits or mix-ins inside
of constructor functions. They make different
decisions. You can compose this stuff
a lot of different ways, because you’re always sort of
cobbling it together from the raw material
that’s already in front of you. It’s incredibly powerful, but with that power
comes the requirement that you have to get a bunch
of people to agree with you about how to use it. And in this case, a bunch of well-meaning
library authors came up with really good solutions
that fit their constraints. And in this case, they all differ
a little bit in terms of the underlying semantic, and
that’s a little bit frustrating when you want to just
share a little bit of code with somebody over there. So what we’d like to do
is say what we mean. So this is a little bit of code
that comes from Marcin Wichary’s
awesome Pac-Man demo, but this wouldn’t be
how you’d write it today. This is how you’d have
to write in the future. Or this isn’t how you would
have to write it today. This is what you would
like to be writing. You’d like to say,
I’ve got a class. It’s got a constructor body,
and it’s got some methods, and then I’ve got
a subclass which, you know, wires with that
prototypal relationship with the other thing.
It’s got a constructor body, and it defines some properties
on its prototype. What we’d like to do
is have this syntax map to exactly what
we saw before, right? We don’t want to change
the fundamental idea of what the language is. Prototype based,
functions as first class, closures to carry state,
top to bottom evaluation, delegation and not classes. When we introduce a syntax
for the word class, right, what we would like
for this to have happen here is when we evolve
the language, we want to hold on to
that fundamental set of things that define JavaScript
as JavaScript, so that you can understand old
code in the context of new code and that JavaScript can maintain
a lot of that dynamic, which pays off so well when
we need to start doing things that the language
doesn’t provide for us. Because
what we’ve seen today is that we’ve put together a whole
series of things from raw parts, just little raw material, things
that are very high level, very high level constructs that
you’re going to need to use, that you might not expect
to be there on JavaScript, but JavaScript
provides them for you. And it’s easy
to love a language that gives you
that kind of power. So we wanted something that we in the standards committee
call de-sugaring. And de-sugaring
is the concept of when you define a new idea,
or you define new syntax, or a new semantic
in the language, it would be best if we could
describe that new thing in terms of the stuff
that’s already there. So if I describe
a new language feature by what it would be like
if I’d just written it all out, we can start to say, aha. This fits
or this doesn’t fit with the way we start to use
JavaScript today. So this is an example
of what I’d like to write in the new style, and what
you would have to write today to go make this all
work in the old style. Okay, that’s a lot,
and it’s a lot of boilerplate that we shouldn’t
have to write. The same thing goes for
a lot of sort of little syntactic niggles. So let’s say
I want a function that takes variable arguments. Today, in JavaScript, I have
to go unpack those arguments out of an explicit
arguments property that’s available
inside the scope of any– inside of any function. So if I want a default value, I have to go
provide it for myself, and if I want to go grab
variable array arguments, I have to go grab the–turn
the best of the arguments into an array,
using array.prototype.slice, pass it in to the arguments
object as the scope, and then say give me everything
after the first one, right? And then create me
the list of parameters. That’s a lot of boilerplate. It’s sort of hard
to read that function, if you don’t know this
particular sort of pattern, and then to understand what
it is that it’s trying to do. It’s much better
as a language, if what we get to is a place
where we can say what we mean when we’re writing
our functions. I’d like the format
to have a default property of a blank string,
and I’d like the parameters that you don’t have allocated
to some named argument stashed away in an array
called params. That’s a pretty common thing
to want to do. And so this sort of thing
is coming in the next version of the language, and last week at JS Conf
and again at Node Conf, we started talking
about some work that we’re doing on the Chrome
Team with the JavaScript and JavaScript compiler
written in JavaScript called Traceur. And Traceur’s goal is to help us design
these new language features in a way that works really
well by trying them out, because language evolution
isn’t a straight line thing. You know, we said that all these
libraries have different ways of doing a lot of the stuff, so what we’d like to do
is figure out what’s the best pattern
or practice? What’s the thing that
we would really like to blast? Or when there is
a new semantic that we can introduce
into the language, what is it that we would be
trying to say in JavaScript directly? And so this way, we sort of
have a way of, at runtime, running this compiler over
some piece of JavaScript written in the new syntax
and have it do something in the old syntax. So in this case– I’m going to go grab something
out of the parameters, and as you can see, it’s
recompiling here, as I type. And now it has– ah, yes, there we are. Now it’s created
all of the stuff that I was going to have
to write out by hand. It’s just compiled that down from the new syntax
to the old syntax, and I can run it. I should be able to run it. man:
[indistinct comment] Russell:
Ah, yes, good call. Great, there we go. So this is a tool
that we’re starting to use to help inform
the language evolution in order to help us
prototype stuff fast, get feedback
about how it works, and so we can
start to understand how the new stuff that
we’re adding into the language fits with the old stuff
by writing real code in it. And as we work
in the standards committee to help make this stuff reality,
this sort of tool, I hope, is going to
make it possible for us to evolve faster and evolve
in a straighter line with the existing versions
of JavaScript, because what we don’t want
is for us to add new things
like the idea of a class and have it be at war with the
idea of prototypal inheritance or functions
as first class objects. We want to continue to help you
build on these core fundamental, really powerful building blocks
in the language without introducing
new sorts of ideas or overhead that you have to consider
when you’re writing your code. And so Traceur, again,
is an effort to help us understand and experiment
with the language, and it’s available as an open
source project on Google Code. You can use it today, both on
the server and on the client, and you can start
to play with it. You can start to write
real code in it. There’s a read, evaluate,
and print loop that you can just go to
and start typing code into. So I won’t belabor
that anymore, but what we’re really hoping
for is that you can start to use a lot of the new features that
we’ve started to play with. We have a list of features that
we’ve implemented in Traceur, and that’s expanding every day. But things like modules,
classes, and traits, asynchronous programming– Asynchronous programming
is something we have to do all the time, and we wind up
doing it with a callback system. It’d be great if
there was support for that in a language that we didn’t
have to continue to write the same boilerplate
over and over and over again. Destructuring assignment,
like we just saw, and the ability to use
the prototypal sort of style of extension,
but have it happen in a way that doesn’t conflict
with everybody else’s objects in the system. Those are the sorts of
high priority work items that we’re starting to use
Traceur to evaluate designs for, and we’d love your help. We’d love for you to start
using it, testing it out, working with the system,
and helping us write code in the new style,
so we can understand whether or not
it’s actually good. So Traceur is one idea
to help us get there. We need implementations early
to inform the design process for the future of the language,
so that the things that you do in the language now
carry out into the future as core idioms and core concepts
that you can rely on there, too. But we need those things
to eventually trickle down into real, live implementations,
V8, other JavaScript engines, and we want to make sure
that these things are available to you quickly in
the fast-moving constituencies. So if you can start to use this
stuff in the Chrome Web Store– because almost everyone in
the Chrome Web Store gets– or who you can target
through the Chrome Web Store gets the latest version
of Chrome within a week– that’s really good. We can start to get fast
feedback in the language and in the design of the
next version of JavaScript based on your feedback
about what’s working and what’s not in ways
that we couldn’t before. The lead time on a new version
of the language has been years– in some cases,
closer to a decade. And so you can follow along
the ECMAScript wiki. I realize this is–
the link is a little bit long,
but there’s a list of accepted proposals for the
next version of the language. That’s going to be
somewhat formalized in the next couple of months. And as that list
is locked down, we’re going to continue
to iterate on those proposals. They’re going to get
new syntax. Things are going
to change there. But the list of things
that are in the proposal stage for Harmony are the set
of things that we, as a committee,
have agreed to go work on and standardize together. And so Traceur
is going to continue to follow that evolution and allow us
to start to work in ways that give us quick feedback
about whether or not we’re doing the right things
for you as you’re writing large
pieces of JavaScript. Okay, questions? man: Hi. So the common JS
modules specification has like a really simple
require and exports that really doesn’t–
that–it’s kind of– it doesn’t factor in,
you know, how things
get loaded or whatever. It’s really just a binding
mechanism between disparate name space. That seems ultimately
simple to me, but it doesn’t seem like Harmony
is going in that direction. Russell: So the simple
modules proposal gives us a way
to have a first pass. So…sorry, I should run this
backwards. The common JS module system
sort of is implicitly server JS. You kind of assume that
the thing that you’re getting in the next statement
is cheap to fetch. And so what we need
for the client is an ability to make the
require and provide statements look apparently synchronous
but have them operate asynchronously on the network,
which means that we want to get the transitive closure
of all of the dependencies that your module needs. man: Then you’re kind of
mixing like load, the loading and– Russell:
They are mixed. There’s no way
to unmix them. Because of the way
that JavaScript evaluates top to bottom,
we either have to– and because
it runs on the UI thread, we either have to block
the entire client while we go fetch resources,
which is what happens with the document.write,
that sort of thing– man: Yeah, I see
what you’re saying. Russell:
Or we have to find a way to accommodate asynchronous
loading in the syntax, and that’s what the simple
module proposal does. man:
I see what you’re saying. Russell: Which is
fundamentally different, because we can use syntax
to do that in a way that common JS can’t. man: Yeah, I use a system where
I kind of–you use common JS on the client, but I don’t–
I allow for, like, forward references.
Russell: Right. man: So like, those things,
they get resolved at a later time, so you can’t kind of use them
completely until later. Russell: Yeah, I’m really
hopeful that we can get the semantic that Dave Herman
has put forward, because it really does give us
the power to not force you to think about when your code
is going to run. If you say require in one line,
you can use it in the next one, and I think that’s
a key usability feature of a language improvement
in this area. man:
Question. On the last slide, one of the things you mentioned
was asynchronous programming with JavaScript. And, you know, like Node JS
is one of the new frameworks. I’m wondering if you can talk
a little bit about some best practices for
how to handle error conditions or exceptions when you’re
doing an asynchronous call that may not be
in the same call stack as when you actually
executed the call. Russell:
So this is a hot topic. The asynchronous pattern
that seems to have won the most mindshare is something
like deferreds or promises. Again, the common JS guys
have done great work there. And so those systems
tend to have some error handling callback
that you can register, so that if an error does occur,
you can be notified of it. I actually was talking with
the Node JS guys just last week in Portland about exactly
how they want to do this, because I’m hopeful
that what we can do is build on top of built-in
language deferred or promise API,
the ability to use the weight or async keywords to go help
mark particular methods of returning
these deferred objects, but error handling does turn
into a primary question then. So what they came to, and I think
it’s a pretty good answer, is that you have
a single callback, right? And that needs to be
also informed of errors. But you can have
an optional second callback, which will be told
about error conditions if you choose to handle them
independently. And I think,
you know, the idea that you’re not going
to have to deal with errors in the primary callback is a little bit farfetched, and so I think that’s maybe
a good trade-off. But it is an open topic. We probably need
language level support for sort of moving
stack traces. Like, if I throw in one catch
here and then re-throw the exception someplace else,
we need some VM or language level support
to help us make that reporting cleaner and nicer. And I think
that’s another important area that we might be able to help
tie these things back together, once we go async.
man: Okay, great. man: Hi, I just wanted to know
if there was any interest or effort within Google
to do some more of the more server side JavaScript,
stuff like Node JS, and maybe any possibility
of ever having that available like on App Engine. Russell: I can’t speak
to future product plans, but I can say that the VA team
is working closely with the Node team to continue
to make Node faster. We care a lot about
their use cases, and we want to make sure
that we’re supporting them. man: So looking at the Traceur
function and the no sugar, de-sugaring, in Lisp,
this was done because they had
a powerful macro facility, so that the developer could
actually introduce new syntax into their programs and define
the behaviors in Lisp. Is there any thought of
doing something like that in JavaScript? Russell: We have a hard time
with that in JavaScript, because we have both statements
and expressions, and we have, you know, a lot of complex grammar
that’s not movable. And as a result,
any macro facility is going to quickly
become undecidable. And so I think
we’re in a place where macros, the way I think you want them,
aren’t possible in JavaScript. New syntax, specifically, is going to have to continue
to happen through the committee. So I think there are places where we can carve out
some stuff. There’s been some good work
in string formatting, for instance, to make it
possible to plug in– through protocols–some new
behavior into existing syntax, and I think that’s maybe
the promising way forward. man: Yeah. man: So did you know
that you can build Firefox with support for Python
as a scripting language? Russell:
I’ve heard tell of this, but it’s been that way
for many years, as I recall. man: Yes, debug build
with Firefox comes with it. More seriously,
what do you think of GWT or more usefully Pyjamas
as actual development platforms instead of writing
direct JavaScript, and using the richer type system
of Python or Java instead of the bare bones one
in JavaScript? Russell: Type systems
are really great. I think that it’s a key
missing feature from JavaScript specifically because what
you wind up writing, again, is a lot of boilerplate
to help you test whether or not you were actually
tall enough to ride the ride. You actually have to
sort of go cart around a lot of this
testing magic. I’m not hopeful
for type systems. This is my personal opinion. I’m not hopeful for type systems
as a be all and end all sort of verification system
for your program. The web is too dynamic. Client-side programs
are too dynamic for that. We’re dealing with
user behavior a lot. Instead, what I’d like for us
to get to is a place where the syntactic warts
of JavaScript sort of get eased over one way
or the other. Things like CoffeeScript are pointing
in a good direction here, where you can sort of come
back up with some new syntax, and hopefully that’ll
eventually work its way into the language. But things like
the module that are– they’re going to have
an analogous API, again, building a protocol that you can
plug into with your own code, and that API will allow you
to do things like run the CoffeeScript compiler
or the Pyjamas compiler across loaded modules
before they’re run, which means that you can
sort of have runtime support for those built-in. I think the–you asked a
question of what do I think about those tools as a way to do
production work. If your language veers far
enough from the core semantics of JavaScript, you wind up
not just with the ability to do all sorts of tooling
and stuff that comes along with your source language,
but you also wind up with the need for the runtime
to do dead code edition. You need to go and sort of
not just do a one-for-one translation down to the
analogous statements in the other language,
but you have to make sure that the semantics are right. You have to make sure
that you have code in there to support any differences,
any impotence mismatches between the two languages. And so I’m much more hopeful about things like CoffeeScript
and the Traceur editions because they don’t add
a lot of extra stuff, because the languages
aren’t that far away in terms of core semantic. man: All right,
thank you. man: Hi, one kind of application
domain that could benefit from scripting
that’s not really– doesn’t have a solution today
is a native Android app. So I wonder if there are any– we’ve dabbled with,
you know, plug-in Rhino and things like that. I wonder if there’s any activity
in that area right now. Russell: I think you’d have
to ask the Android team. I’m sorry, I’m not up-to-date
on what they’re doing there. man: Okay.
Russell: Thanks. man:
I had another question. So in my Python programs,
I like to use sometimes multiple inheritance,
and I have complex– Russell: C3MRO,
right, yeah. man: Dependency graphs
and so on, yeah. So and they have a method
resolution order in Python that allows you to call
the super classes methods, you know, exactly once
in the right order, and– or at least
a well-defined order. Is anything going on in Harmony
for allowing for something like an MRO type
call graph resolution? Russell: I don’t think
we’re going to break the idea of a single prototype.
man: Right. Russell: So the analogous
thing here would be multi prototype languages. I’m hopeful
that what we’ll get done is something like
Tom Van Cutsem’s Traits semantic, where we can add
a syntax for defining a set of things
that you would sort of– like we did with mix-ins,
add to the class, and then do conflict resolution
with syntax. Because what you’re trying to
say in a lot of these cases isn’t, I’d like for you
to sort of decide for me which of these things
I am at runtime. It’s not really a–
an “is a” relationship. It’s sort of a “has a”
relationship, what you’re saying. I’d like this new behavior to also be available
to my object. And if you can factor
those things out, it can help with composability
and then eventually with type testing. And I think Traits are where,
at least I’m hopeful, that we’ll go
to make a lot of that easier. man: Yeah, I use a wrapper
where like I kind of build a copy of
a well-defined prototype chain, specifically for this
particular set of mix-ins, and so like
you can kind of emulate, you know,
by specifically listing the order in which you want
things to be resolved and kind of get the behavior
for that in JavaScript. man: Mainly curious, do you know
whether Traceur shares common lineage with
the cross interpreter in Google Widget Toolkit? Russell: The Traceur code base
is brand-new. It’s a, you know, a new client-side compiler
that we wrote, hand-built parser,
that sort of thing. man: Thank you.
Russell: Yeah. All right, one more.
All right. man:
So I’m a C# developer, and I’ve stayed away from
JavaScript for a very long time, mostly because I didn’t–
I knew the what, but I didn’t know the why,
and that’s been really good in today’s session. I’d like to continue
exploring. Can you recommend any reading–
specific reading material? Because, of course, I could
always do a Google search. Russell:
Yeah. man: But that would continue
along the path of not just the what but the why also. Russell:
The latest version of “JavaScript, the Definitive
Guide” is pretty good. I recommend
“Eloquent JavaScript.” It does a great job of sort of
introducing these core concepts and getting you through not just
sort of what you can do. I didn’t talk a lot
about how DOM interacts with all of these things. My recommendation
is that you find someplace to start playing with a language
that’s not a web browser. I mean, web browsers
are really handy. You can start to sort of like
make this all happen. But if you just sort of play
with the command line in the browser or start to work
with a local copy of V8 or Node JS,
you can really get a feel for what’s in the language
and what’s not in the browser. JavaScript takes–in almost
every environment, it takes a lot of its identity
from the standard library that sort of
it’s been wedded to. And in most cases, because it has
a very small standard library, all of that is in
the environment. And so the more you can sort of
remove those potential hurdles or sort of impotence mismatches with what’s just
in the language, I think the faster
it’ll help you learn it. Yeah. man: Actually,
in a similar situation as the previous question,
which is I stayed away from JavaScript
for a number of reasons. Probably
one of the biggest ones was the lack of debug support.
Russell: Mm-hmm. man: And the fact that you have
unexpected surprises, like being able to overload
the array constructor, that lend itself to,
you know, security holes, whereas someone coming
from another language isn’t expecting that,
and they don’t even consider that as a possibility
when you’re looking at code. So specifically, is there
anything that’s talked about being added, where–
when you talk about modules, that the module can set up
certainly like preconditions? I’m expecting these sets
of things to be true, like the array constructor
cannot be overloaded, or anything else
where you can say, flag, this is going to be a problem
or not going to run right. Russell: So one of the big
things that’s happening with the module syntax
is that we’re removing the ability to share globals,
so you won’t have a single shared global,
which is going to be big, to prevent people from sort of
blowing your own legs off. The other thing
is that ECMAScript 5, the version that was just
recently ratified, implements what we call
a strict mode. And strict mode turns off
some of the worst foot guns. It helps keep you out of trouble
by giving you more and more pre-checking for things
like uninitialized variables, that sort of thing,
where it keeps you from sort of tripping over yourself
in some pretty common areas. It’s not perfect,
but it’s certainly a start. So use strict inside
of all of your functions, and you should be good to go. man: And what about the idea
of like official debug support? Russell: So that’s
an engine-by-engine thing. The topic of common stack traces
has been raised a bunch of times, and it’s
going to be very difficult, because that constrains
our ability to optimize. So things like
alighting away dead code, those are the sorts of things
that are going to be hard to do if we have to agree
on a stack trace format. So what we do have is
really good support, say, in the Chrome web inspector
for setting breakpoints, future breakpoints,
getting call stacks, and soon the ability to
sort of wire up line numbers to source code. So yeah, debugability
is a hot topic. It tends to happen
through the browser and not through
the language runtime. man:
[indistinct] Russell: So the question was
will a closure compiler help with the debugability.
If the closure compiler has– man:
[indistinct] Russell: Oh, will the closure
compiler help beginners? No. It’s designed
to help folks who know that they have a problem
avoid having problems. Okay, cool. Thanks again for coming,
and I’m looking forward to it.

100 thoughts to “Google I/O 2011: Learning to Love JavaScript”

  1. So we should love javascript because it has allot of features which allows it to simulate object oriented languages? Seems to me like a reason to stay away from javscript.

    Feel free to correct me.

  2. good. but it's little bit messy, with even some bugs in slides.. might be confusing for javascript beginners, when new features pop up without further explanation of basic principles. i understand why you did not include douglas crockford's lectures in the discussion – he's from yahoo and so much better lecturer. anyway, keep up the good work.

  3. @blogpedia You should really also consider mixing JavaScript,Java, and HTML5 it will make your page and application better.

  4. @ablepilot12 Good to see you getting into it early I just started a few weeks ago on HTML and CSS and I know them well now. I just need to learn Javascript to make awesome stuff. 😀

  5. @XPantheX Sometimes there's such a thing as too much jargon. Function objects -> The language isn't object oriented so they use functions as objects and all them function objects. Hang behavior off -> "smart" way to say it can "tell" stuff how to do stuff. You don't have it tell stuff what to do by extending public api -> you don't add everything it could possibly do to a resource for portraying what it can do. There's too much. Scope is like blinders for a horse for the program/components.

  6. hi alex thanks for your video i do need more information about how to get videos on java would it be possible to help me with it

  7. LOL I loved the "foot guns" comment as well and looked it up "like using a loaded shotgun as a golf club". Great video on where JS came from and where it is going..

  8. Very good presentation. Probably not for people completely new to programming, but then again I don't think Javascript is the ideal language for people that are new to programming anyway.

  9. Please, can some one write all recommended literature (from here 59:37) in comments. Thanks, спасибо.

  10. ActionScript 3 (AS3) is like Javascript sister since they're ECMAScript compliant. At 11:39, same code can be written in and results the same. However, AS3 does have much more support in terms of OOP.

  11. @arkdrag JavaScript Is a good language for beginners. Usually, developers from programming backgrounds can get confused from the language, due to prototypes, loosely type language, no classes etc. i believe it greeted more complicated from programmers from different backgrounds

  12. getCtr() is only called once. it returns another function which is then subsequently called. getCtr is the closure in this example.

  13. I try to learn javascript since two years, this video feel the AHA! moment of the javascript.

    A must must see.

  14. He speaks too fast for this topic. It is my second spoken language, I pick up every word, but you have to think of what he said as a concept. 🙂

  15. thank you ! this is what you need to see if want the best "intro in a nutshell". everything should fall into place after this. highly recommended.

  16. Guys I found a site where you can reverse phone for free, if you go to my profile you'll see the link on the descrption

  17. Anybody knows how he created that slideshow? I like how it display part of the previous and next slides during the presentation.

  18. It would be a shame if you did not bulk up when normal people are able to bulk up so easily with Atomic Max Muscle (check it out on Google).

  19. Shouldn't in 27:22 be

    console.log(this.item);

    instead of :

    console.log(this.value); ?

    He defined the item and assign to the "item" the string "value" …. not reverse.

    Thank for answer 🙂

  20. JavaScript is Father of all languge and all other languages in future is only before . JS … thats i can say after watching this video.

  21. yeh thats tue but i m talking abt Future and you are talkin abt Past .. C , C++ is Good but not more usable in future ..

  22. It's never ever gonna be able to do the computations C++ can.. Java will only be usable on the web, and programs which doesn't require much.
    Also java's the one of the biggest reasons of most of the pasts virus infections, and current ones…
    If the future will be utilizing easier languages while them being computational inferior, we'll be going backwards not forwards.

  23. so wats your View java Script is not usefull language …? according to me .. its good Language .. but the problem is their is not many people our their woh understand how to use this language dont know power of JS it most flexible language i know … now its up to you .. and One more thing ECMA script-6 is Out their watch first and than .. reply me Back thanks .. bro

  24. ok .. i dont understand … how to speak with u in Words … One thing we can do .. lets Meet hear @ youtube after 10 years and decide .. result … Thanks for All reaply and its was nice to talk with you Brother ….

  25. Considering the huge growth and performance improvements in web technologies over the past 5-10 years, a lot suggest that JavaScript will be the future of app development..

    The power of the web greatly outweighs the computational power of a single computer, and harnessing that power is increasingly easier with JavaScript than with C++..

    Take a look at chromeexperiments[dot]com to see examples of how far the power of the web can take you..

  26. Sure, C++ is more powerful for computationally heavy and specific tasks, but how often do you actually need that kind of power as a developer..? The most common use cases like graphics is already built into the layout engine of the browser ready for JavaScript to utilize.. Pretty much whatever would be too slow to do in JavaScript can now be delegated to the browser or the server..

  27. Viruses isn't caused by JavaScript, but by the combination of the huge popularity of the web, ignorance of users and crappy browser implementations.. Actually C++ can do a LOT more damage and faster than JavaScript..

  28. thats y whole world are running to learn & Use JS in their Project 😀 …. bro u dont know power of JS .. thats y u commneted ….. 😀

  29. Javascript is good only for the front-end part of the web and the way it is now it won't go anywhere apart from the web. The use is so high because idiots like you can learn it easily and think that you have some clue about programming.. But after you learn languages like C, C++, Java, Python or other paradigms as those supported by Lisp, you will understand how tiny Javascript is and then realize how stupid you are.

  30. This is a really great talk. I didn't understand the significance of a lot of what he was saying the first time I watched it. However, coming back after about 6 months during which time I worked with javascript (intermediate stuff), this guy makes ties in the concepts of javascript pretty well.

  31. I am learning Javascript and PHP and I'm not feeling a idiot. Perhaps you have born with full knowledge of programming, lucky you. Idiot.

  32. Javascript can access hardware but is generally browser limited by design. Nodejs has hardware access as it's run outside of the browser sandbox. The is no programming language war, use the correct language for the job.

  33. You're mistaking java and javascript somehow even though they have nothing in common. Also while js took it's syntax from c, the design of js is heavily based off of scheme and small talk. So js would exist without c, but it would look a lot different.

  34. Even though Node.js provides Javascript hardware access how many actually use it to program microprocessors or write GUI applications? Js is great for the web though for anything other than that it is immature.

  35. I'm glad you've changed opinion from no hw control to poor hw control. It has been used apart from the web for quite some time now (google js uses outside of web pages). Js can be used to do anything as it's a Turing complete language, but it isn't the best suited language for close to the metal programming. It is very well suited for gui apps, and a lot of the recent drive in js has been towards this future (the spa movement).

  36. Have you heard about Morsch Muscle Madness? (do a google search for it) It is a quick way for you to get ripped fast.

  37. Nice talk. I wasn't aware of the core JavaScript ideas @Alex Russell talks about. I'm going to read Eloquent JavaScript right away.

  38. You'll learn more from 20 minutes of this video than reading a tutorial for a couple of hours. You understand the language's core better – but not sure that you will learn to LOVE it.
    Feels like many arguments for the awesomeness of js boils down to ways to compensate for missing concepts.
    For instance at 25:30 there's a great explanation of being able to add properties at run time. But it just boils down to "you can build concepts which are not necessarily given to you in javascript". So that's not a reason to love JS, it just makes you feel like it's a shame those concepts are missing from the start

  39. Great talk! Although, he kept hitting home "top-to-bottom", "left-to-right" as if this is surprising behavior for a single threaded execution environment. 

  40. Composition kicks the crap out of Java-C inheritance taxonomies.
    The ol' ask for a banana, get the whole jungle conundrum disappears when you think DIFFERENTLY.

  41. Composition kicks the crap out of Java-C inheritance taxonomies.
    The ol' ask for a banana, get the whole jungle conundrum disappears when you think DIFFERENTLY.

Leave a Reply

Your email address will not be published. Required fields are marked *