Check out a free preview of the full JavaScript the Good Parts course:
The "JavaScript Fundamentals" Lesson is part of the full, JavaScript the Good Parts course featured in this preview video. Here's what you'd learn in this lesson:

JavaScript is an object-oriented language. An object is a dynamic collection of properties. Almost everything in JavaScript is an object. Object literals are not only a good part of the language, but influenced the development of JSON. While JavaScript does not have classes, it does have prototypes. Prototypes are much easier to work with than classes. Prototypes can utilize delegation or differential inheritance. However, in JavaScript, inheritance can sometimes work against you. Many other data types in JavaScript inherit from Object. These include Number, Boolean, String, Array Date, RegExp, and Function.

Get Unlimited Access Now

Transcript from the "JavaScript Fundamentals" Lesson

[00:00:00]
>> [MUSIC]

[00:00:04]
>> Douglas Crockford: JavaScript is an object-oriented language and almost everything in the language is objects, but it's a different sense of object than in another languages. An object is a dynamic collection of properties, which means that new properties can be added to an object at anytime. Every property has a key string that is unique within that object and that key string is used retrieve the values.

[00:00:34] So the three basic operations on object are get, set and delete. Get uses the dot notation or the bracket notation. It turns out they're fairly interchangeable, which is different than most other languages generally brackets and dots have different roles. Here they both do the same thing. So you can either have a constant name or you can have an expression,, which resolves into a string which is that name.

[00:01:01] They both do the same thing, then set is the same thing, except used with an assignment operator. Then delete is a prefix operator, which is rarely used. But if you do use it, you just put it in front of a name of a property and it causes the property to be removed from the object.

[00:01:19]
>> Douglas Crockford: JavaScript has object literals, this is one of the good parts of the language. It is also the inspiration for the JSON Data Interchange Format. Object literals are very expressive way for creating a new object where you have a name followed by column, followed by a value. You can have as many of those as you want separated by commas and that creates a new object contained in that material.

[00:01:43] In ES5, we added a meta API which allows you to do the same things. You can say, Object.defineProperties passing an Object.create and Object.prototype and foo. That does exactly the same thing. You might ask well, thank you so much for allowing us to write it this way. What's the value of that?

[00:02:04] The value is that you've got more control now that you can decide what the thing inherits. In particular, you can have it inherit from null now,, so that there's no inheritance happening at all which for some applications turns out to be really beneficial. Also we've got these three attributes, which you now have control over.

[00:02:22] They've always been in the language. But until ES5, you couldn't get at them. So you can now make a property be read only. You can now make it be not enumerable, so that it will not show up in a for in iteration.
>> Douglas Crockford: So most object languages have classes.

[00:02:43] JavaScript doesn't have classes, it has prototypes. It turns out prototypes are the more powerful idea and the proof of that is that you can simulate a class system easily in a prototype system. It's really hard to go the other way. So it's much easier to write in JavaScript in a Java style than in is to write Java in a JavaScript style, cuz Java just isn't as powerful.

[00:03:09] JavaScript is more powerful, but I recommend not writing JavaScript in a Java style,,because you are losing most of the benefit of the language. You're still writing in the style of the language, which isn't as good as this language.
>> Douglas Crockford: So in this language, you work with prototypes and it turns out working with prototypes is much easier than working with classes.

[00:03:35] So you make a new object that you like and you can create new instances of that language that inherit from that object using Object.create and then you can customize the new objects, adding new properties or modifying properties as you need to and that's it. That's all you have to do to manage your objects.

[00:03:54] Whereas in a classical system, you first have to classify everything. You have to make a taxonomy. You have to figure out what the relationship is gonna be between all of your classes. And usually at the time you're doing that, you don't not yet have perfect domain knowledge as to how it's going to work out.

[00:04:09] So you make guesses. And invariably, you get stuff wrong which then means you have to work with an inefficient object system or you have to refactor and refactoring is difficult and error prone. All of that is completely avoided in the prototypal system. You just make objects. So having that level of indirection removed just makes everything easier.

[00:04:33] So this is sometimes called delegation where an object can say anything that I don't know how to do, ask that object to do it for me. So objects inherit directly from other objects. So there's no classes getting in the middle. It's also sometimes called differential inheritance where each new object only has to contain the material necessarily to distinguish it from the thing that inherited from.

[00:05:03] JavaScript has a new prefix operator which in my own practice, I do not use at all anymore. But if you wanted to write it as a function just in order to understand what it does, this is what it does. It creates a new object that inherits from the function's prototype and returns the result of calling the function on that new object.

[00:05:33]
>> Douglas Crockford: So not surprisingly, there a lot of things that JavaScript didn't get right. One of them was inheritance sometimes works against you. So here, I have an application where I'm gonna count the number of words in a text. I'm gonna use a regular expression and break some text into a bunch of words, and I wanna count the number of occurrences of each of those words.

[00:06:00] So I've got my little bumper count function and then a parse at each word, and.
>> Douglas Crockford: Wait a minute.
>> Douglas Crockford: Okay, so the naive way to have written as would be to simply bump word_count for every word that I get. But that would fail if the word was constructor, because it turns out every object inherits the constructor property.

[00:06:33] And so that's a function. And if you try to add one to a function, then you get weirdness. You don't get one. So it would fail. So you would have to instead look at.
>> Douglas Crockford: What the value was an d look at its type. Make sure it's a number.

[00:06:53] And if it is a number, then I can increment it. If it's not, then I have to assign it. So there's some defensive programming that you have to do which should have been unnecessary, but is necessary, because of unexpected consequences of inheritance.
>> Douglas Crockford: That description expired and that we can now inherit from null that solves a problem for this case.

[00:07:17] Functions inherited from a prototype are included in the for in enumeration, which is usually surprising. Usually when they doing for in, it's because you've got a collection of similar values and you're not expecting any methods to be included in the numeration. And because you don't have control in your code of everybody who might ever add anything to any prototype, it is unfortunately necessary to filter the results in for in to make sure that you're not getting stuff that you don't expect.

[00:07:46] You can be testing for the type of things as we did in the earlier one or looking to see if it's part of hasOwnProperty, which means it's not an inherited property. You really have to do this. Otherwise, there is a possibility that your code's going to explode in the future.

[00:08:07]
>> Douglas Crockford: One problem with hasOwnProperty is that it's a method and not an operator. So if it turns out that hasOwnProperty is also the name of a data value, then it's not gonna be available as a method. And so you gonna get failure then. So the way to get around that is to find a place to where it's guaranteed to be, which is Object.prototype.hasOwnProperty and then call method passing in the other stuff which is horrible.

[00:08:36] But in the worst case, that's the most reliable way of doing that filtration.
>> Douglas Crockford: Keys must be strings, which I think is one of the errors in the language. It would have been much better if keys could have been any value in particular objects, so you could have associations over objects.

[00:08:55] Unfortunately, Brendan didn't do that. So when you pass it a key, it will convert it to a string automatically coursing it which works, but its lacks some of the power that it could have had otherwise. So there are lot of other types in the language, which all inherits from object.

[00:09:17] Everything is an object. So numbers, Booleans, strings, arrays, dates, regular expressions and functions are all objects in this language.