Placeholder Image

字幕列表 影片播放

  • 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.

Russell: Good afternoon.

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

B1 中級

愛上程式語言就從現在!Google I/O 2011: Learning to Love JavaScript

  • 11822 190
    Steven Chen 發佈於 2013 年 03 月 15 日
影片單字