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

An object is a dynamic collection of properties. Every property has a key string that is unique within that object. Doug shares some APIs for working with Objects. He also talks about concepts like classes vs. prototypes, delegation, and prototypical inheritance.

Get Unlimited Access Now

Transcript from the "Objects" Lesson

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

[00:00:04]
>> Douglas Crockford: So JavaScript is an object-oriented programming language which, but what it thinks an object is is different from the most other object-oriented languages. In JavaScript, an object is simply a dynamic collection of properties. Every property has a key string that is unique within that object, and that key string will be associated with any value.

[00:00:27] You can get a property from an object by using the dot notation or the bracket notation, they can be used, in some cases, interchangeably. If the bracket contains an expression which is a string, which is the same as a name, then you'll get the same property. That makes it possible to dynamically get at things without use of a reflection API.

[00:00:51] You can set of properties of an object simply by assigning to those properties. You can add new properties or modify old properties simply by assignment, and you can also delete properties from an object using a delete operator. Although, I very rarely see this used. Generally, once an object is made, it keeps its stuff.

[00:01:13] One design mistake in JavaScript is that the keys must be strings. It would've been better if they could've been any value, but they're not. So you can pass any type into the brackets, JavaScript will turn that into a string. So the beans, effectively, the values have to be strings.

[00:01:34] We have a very nice object literal notation, JavaScript's object literal notation was the inspiration for the Jason data interchange format, the world's most loved data interchange format.
>> Douglas Crockford: You've got curly braces that identify the object, then you've got named fields or properties within the object. You don't have to put quotes around the names if the names are valid identifiers.

[00:02:05] If they are not identifiers, then you need to put the quotes around them. So most object oriented programming languages are classical. They're all about making classes where objects are instances of classes and classes inherit from other classes. JavaScript has a much simpler, much more highly evolved design, which is based on prototypes where objects inherit from objects and that's it, there are no classes.

[00:02:33] This was the idea that we got from the self, which was an improvement over small talk. But it's a really controversial idea and most people who are writing in this language do not understand how this really works, but we're gonna talk about it. So working with prototypes is actually very easy.

[00:02:52] You make an object that you like using any of the techniques available for making an object. You can create new instances that inherit from the object, and then you can customize the new instances by assigning new properties or replacing properties. The classification and taxonomy operations that you have to do in a classical system aren't necessary, which turns out to be a huge win.

[00:03:19] So if you're working in a classical system, when you start off, you have to classify all the objects. You have to figure out what are all the objects, what are they composed of, how are they related? Then you make a taxonomy in which you figure out what's going to inherit from what, what's gonna implement what, and it's a really complicated hierarchy.

[00:03:35] Usually, you're doing that work at the point in the project, usually, the beginning, we have the least understanding of how the object system's actually gonna work. Which means it's almost certain that you're gonna get it wrong and you see that in that things don't compose properly. You just can't, they don't work.

[00:03:56] You find yourself wishing they had multiple inheritance, cuz there's no way to get from here to there. And as you layer in more and more classes on top, you find that that brokenness starts to seep up into all the higher layers, and eventually reach the point where it's so broken that you have to refactor, which means have to tear it all apart and put it back together again.

[00:04:16] Which is really dangerous, cuz there's a chance it might not ever go back together again, and all of that is due to the coupling of classes. And if you get rid of classes, you don't have to do any of that, which is really quite remarkable. So the model that JavaScript provides is sometimes called delegation, where an object can only do what it can do and if there if it's asked to do something that it can't do, it will designate another object to do that work on its behalf.

[00:04:45] This is also called differential inheritance, where each object will only contain the material which distinguishes it from the object that it inherits from. The primitive in JavaScript for making a new object is object dot create, where we pass it an object, which unfortunately is called a prototype, and we make a new object that inherits from the old one.

[00:05:08] The word prototype here is problematic because it's so overloaded. All it means is, this is the object that we want to inherit from. So let's diagram this. I'm gonna make up an object called mother, which will have two properties, a and b, whose values will be 1 and 2.

[00:05:29] And this is the data structure that is created. So we've got our key value pairs and we also have invisible pointer to object.prototype. So whenever you make an object literal, it will ultimately inherit from object.prototype. Then if I make a daughter object, I'll use object.create mother, so I now have a daughter.

[00:05:53] So I've got an empty daughter object which inherits from mother.
>> Douglas Crockford: So if I say daughter.b + 2, originally there is no value here. So we get the inherited value of b, then we add two to it and store it in the daughter. So storing operations will always go into the top most object, but reading operations can go all the way down the prototype chain.

[00:06:23] And we can have these chains go as long as you want. Generally, chains in this language tend to be very shallow. We don't get the deep hierarchies that you tend to see in classical languages but if you wanna go deep, you can. Then, we can add material to the daughter object which has no relation to the mother object, so we can add more stuff.

[00:06:48] So generally, the way we'll use this is the mother object will be where we put the methods, and then the instances will inherit those methods, okay?
>> Douglas Crockford: There's also a form Object.create (null), which will make an object that inherits nothing. So you get an object that does not inherit from object.prototype.

[00:07:12] This is handy if you want to make something which is just a container of stuff and you don't want to be confused by stuff that you might inherit from object.prototype. So this will act much more like a hash table.