 So before I start, let me actually warn you that I'm not a JavaScript expert. When I work with JavaScript, I usually end up in some roadblocks with the different ways of the works, the different way JavaScript works. So I spent some time trying to understand how it works and I'm going to actually share my experiences with you today. So the outline of the talk is going to be something like this. So I'm going to talk about what's an object and what's a function and then we'll slowly move on to prototype and understand how it works. Then we'll see the new operator and then we'll try to actually implement the new operator and the instance of operator. And then we'll try to see if we can implement the classical enhancements like we see in other languages like Java or Ruby in JavaScript. So it's an object, it's a simple hash map kind of thing. So you have an object called p, you're defining x and y two properties. So they're called properties in the JavaScript world. So when you say a equal to p of x and b equal to p of y, you can actually get those values there. And in fact, you can actually change these values anytime. So you can actually assign new variables at new properties at runtime. That's about objects. So that's a simple way of creating objects and using them. Let's actually look at functions. Functions are actually a special type of objects. They're also objects, but they are callable. So if you look at here, I've defined a square function. What it does is it just computes square of a given number. The nice thing is it can actually, these are just like any other objects. You can assign them to a different variable and then call it and do all those kind of things. And as I said before, they're like any other objects. You can actually add new attributes straight and then access them and do all those kind of things. So now there's some magic thing called this, which we always get confused when you work with JavaScript. So let's actually try to see what it is. So the body of the JavaScript function, if you look at here, there's a function square. Inside the body of this function, it has access to two magic variables. It's this argument. The value of this depends on how the function is called. When you call it as f, then this becomes a top level object. We'll see what a top level object is. But when you call it as a.f, this becomes the a object. So what's a top level object? In JavaScript, there's always a top level object, which keeps all the global variables. When you define x equal to 1, it's actually added as a property to the global object. So when you're working in a browser context, the global variable, the top level object becomes the window object. But there's another way to call a function. You can actually say f dot apply and then pass arguments here. So calling f2 is same as f dot apply null comma 2 as a list of arguments, too. When you say a.f, when you call a.f, it's same as calling f dot apply a.f.2. So what you're doing here is apply takes two arguments. One is what should be this variable and what should be the arguments. So whenever you are actually saying a.f, it actually means it internally calls f dot apply with a as this. So let's actually look at one more example to see how it works. So I've written a slightly varied version of the scale function that I've already seen before. So what this does is it doesn't take any arguments, but it expects this whatever it gets as to have a value property. So here I've defined n as value 2 and we have defined the function that I've defined. So when you say n dot square, what happens? The function square gets called. What is square? It's a square new function that I've written. Since we're calling it as n dot something, n becomes this object here. So it takes this dot value and then it executes it. So it's exactly the same as calling square meter to apply n and without any arguments. So it's actually tricky, but if you look at other languages, when it's like Python or something, when you say n dot square, you can actually assign it to something else. You can actually say f equal to n dot square and then call it, but it doesn't work here because it expects n to be here and before. So now look at the arguments variable. So that's the second argument that we passed to the apply function. So it's a simple example to demonstrate how you can use it. So there's a function count. It just returns argument dot length. So you can just call count with 1, 2, 3 and it gives you 3. So now look at the new operator. So the new operator creates, so there's a different way of creating objects. In the first slide, we have seen that you can create an object by creating a dictionary like syntax, you define the curry brackets and say x1 and y2, but there is another way to create it that's using the new operator. So here I've defined a simple function called point and I'm creating the variable p, which is using a new operator, new point 1, 3, count 4. So what it does is a new operator actually creates an object internally and then passes it to, passes this to the function that we have defined. So when it's a new point, what it does is it creates an empty object and causes function with the new object as this. So it's pretty straightforward. Now there's something more magic called the prototype object. So if you see, each function has a special property called prototype. So and whatever properties we add to the prototype of the function will be available to the objects created through that function. For example here, the point p is created using the function point. So it can access the prototype, the properties defined in the prototype. Here I defined name equal to point and you can say call p dot name and that returns the same point. So it's like, it has a kind of pointer to that and it actually reads from there and gives you back. But if you add name property to p, it affects only p, it won't affect the prototype. Okay, this is actually very important to notice. So the prototype is only accessed as read only from the object. But when you modify, when you try to modify that property, a new property gets added to that object and the prototype will continue to be the same. So it's typically used for writing, writing fun, adding methods. So typically in the classical class kind of things, you actually write methods, right? So here I've defined a method called magnitude which takes, computes magnitude of that point. So the prototype is typically used for adding functions like this. But even the prototype is not something which is any magic or something. So it's like any other object, you can change it to something else and so it's an example to demonstrate that. So now here I've defined a, X as one in the prototype of f. Okay, so I've created an object called f1 and f1 at x gives me one. So what I'll do now is I'll, I'm changing the prototype to some new object where x is two. So the new object f2 actually gets f of x as two. But what happens to f1 of x? Any, any ideas? It'll be one or it'll be two? No, it'll be one. Because it points to the prototype at the time of object creation. Okay? Once the object is created, you're changing the prototype of f, but the old object still points to the old one. Okay? So to understand this better, some JavaScript engines actually let you access the prototype. So when you say p, p actually has a link to function prototype, right? So some JavaScript engines actually let you access that prototype of an object that's called, with a special property called underscore and square proto. So if you look at p and check if it's the same as prototype, yes, it's the same as for the points prototype. Okay? When you say some JavaScript engine, I would say all JavaScript engines expert one. So you know which one doesn't support it, right? So it's even possible to change the prototype object. So you can actually change it to something else and you actually get f.name as four. So let's actually try to see how actually this looks like. When you create two new objects with using the point function, so when you say p1 is point, new point one comma two, it sets x comma y and the prototype points to the prototype of the function. So actually there is a slight confusion here for the lack of words. We're calling this thing as function prototype and calling this as object prototype. Okay? So here, so I'm really calling underscore and square proto and prototype both as the same name just for the lack of better term. So when you say function prototype, that's the function dot prototype. When you say object prototype, it's dot underscore and square proto. So whenever you access a property, it first looks up the object. When it's not found here, it actually goes back to underscore and square proto and then tries to find it here. So when it's a name, you get the name as point. But when you define a new name, a new name property gets added here. So it won't even go and look in a prototype. So now let's actually see if we can implement the new operator ourselves. So we have seen in the previous slides that all the new operator does is it takes, it creates a new object and calls the function with the new object as this. So let's actually see if we can implement that. It's not really too hard. Okay? So this only works with in the Java's company, square proto is supported, but just for trying to understand how the new operator works really, not really for any real use. Oops. Okay? So like I said, what it does is it first creates an empty object and then it sets the prototype and then calls the function with that object as this argument. That's all. Okay? Let's actually see what it's doing. So first it's getting empty object and then it's linking it to the prototype and then calling the constructor, constructor is a function. Then the function is assigning x and y. Right? So it's the function, the point function is saying this dot x equal to one and this dot y equal to two. So that's how it happens. So the three different steps that we're doing, getting empty object, linking the prototype and then calling the constructor. That's all it does. So it's not too difficult. Right? You can actually see it's pretty straightforward. It just creates an object, links the prototype and calls the constructor. Now, the prototype can be, can actually be tricky. So we have only seen, we have one object and that has a prototype. Okay? What if the prototype itself has more link to its prototype? Right? So it could actually be changed. So let's actually see that with an example. So I've defined two functions, f and g. And what I did is I made the prototype f as instance of g. Okay? Right? So what happens is when you create an object f, it has a property called f. If you create an object of g, it has a property g. And g's prototype has property h. Now I have changed the prototype of f and created a new f object here. What happened when I say x dot h? It'll be h. Yes. But how does it work? Yeah. So if you see that, x is an instance of f. So it points to f's prototype. Okay? f prototype is actually an instance of g. So it actually points to the g's prototype. So it's actually changed like a link list. So when you say x dot f, it looks up here and then says it's f. When you say x dot g, it's not found. So it goes through the prototype chain and finds it here and returns this value. When you, it still, it's not found. It still goes the next level in the prototype chain. It goes up here and then finds it here and then returns that value. Still, if it doesn't find it, it'll go here and then tries to find the next value there. So this prototype can be changed. So it looks like some kind of inheritance. Yes. So this is the technique that we can use to implement inheritance, the classical way of inheritance we see in other languages. So no, actually let's try to understand the instance of operator. We have been seeing that, we've seen in one of the examples that when you say you create an object, you can actually check that object as instance of that function or not. So according to modular docs, it says the instance of operator tests whether that object has its prototype, any of it. So when you call instance of, you give a object and it gives in function. So what it does is it takes the prototype of that function and sees that and tries to check if that prototype is there anywhere in its prototype chain. So in simple words, it just checks if object instance of that function in any of these levels. So if you see here, p is instance of point, but it's also instance of object. So if you look at the previous example here, you have two functions f and g. When you say f is instance of f, it would be true, but it won't be instance of g. But when you change the instance of, when you make this prototype same, both becomes true. Why? Because all this is doing is, it's taking the function, we're giving here, it's taking function and its prototype and then checking if this function, this object prototype chain has it or not. So now, let's actually try to implement the instance of operator itself. That's, even that's not too hard. Like I said before, what the instance of operator is doing is, it is trying to find, it's taking a function object and a constructor, that's a function. What it does is, it takes a function's prototype object and sees that if that's contained anywhere in the object's prototype chain. So forget the first condition, but look at what it's doing. So what it tries to do is, it first checks if the object prototype is same as the function's prototype. If not, it actually, because it goes back to its parent and it stops when it reaches the object. So if you look at the previous slide, when you say x instance of f, it checks x dot prototype is same as f dot prototype. It's true. It returns true. But then check if x instance of g, what it does is, it checks this space. So it repeats with this. Then it changes this object. So then it starts checking here. So this is true. So if you actually, so it goes on like that until it reaches the object prototype. So that's it. So, yeah, so it's a very simple function. It first checks the prototype at the current level and then tries the same recursively at the next level. Now, there is this, I mean, we thought we've got the instance of correctly, but there is a slight deviation from the standard behavior for the primitive types. So when I actually check if one instance of a number says true, one instance of object returns true. But when I say one instance of number, and so when I call it with my function, it returns true. But when I actually use the instance of operator, it says false. You know why? So JavaScript has some special behavior for the primitive objects. So these primitive objects are not really objects in the sense that I've talked before. But whenever you're actually trying to use them in a way like an object, it converts them into the corresponding object and uses that. So I'm actually, sorry, it gets a variable. No, it's not. Even if it acts as x equal one and instance of number, it still fails. Let me actually show you that. So false. So what happens is x is just a plain basic type. But whenever you actually want to say x dot foo or something, it converts it into a number object and then applies this and then executes this operation. When you say x dot foo, it says undefined. But you can't say one dot foo. So when you say x dot foo, what it does is, it connotes one into number one, a number object one, and then changes that. Let's actually see. I've added x dot foo equal to foo. So what happens when you say x dot foo? What do you expect? What do you expect now? No, it's undefined. So what it does is, when you say x dot foo, it creates a new object with the same value and then does this operation and then the object gets lost. This is called auto boxing if you use that term in Java. So when you try to, in Java, when you try to add an integer to a list, it cannot stick to an integer object. And when you try to, say, take the object and say plus one, it converts it to basic integer again. So it does something like that here. So what's happening was, in our case, in our implementation, we're actually trying to call object dot underscore underscore proto. So when you try to access the property, it actually converts it into the corresponding type and takes its proto type. But the built-in implementation is smart enough to handle that. So this difference between the primitive types and the regular types might get into this kind of confusions. It's good to know the differences. So now we have really implemented the new operator and the instance of operator. Sorry? It's not possible because when I'm saying, I mean, I can actually add, especially check, see if it's an integer. It's not really possible, I guess. I mean, I can write a function to check if it's a basic type or not. I can do that by doing this. I'm going to assign something to it and then see if it's not. But I don't know if it's possible to do that. So even if you actually take a string and add an attribute to it, I think attributes you can add to a string probably, but the instance of, there is this difference between the basic types and the primitive types. So you can actually explore by trying different examples. So now we've implemented a new operator and the instance of operator. Let's try to see if we can implement the classic classes and class types in many times like we see in languages like Java and Ruby. So here is what we want. I want to simply create a class. JavaScript has no concept of classes. All it has is objects and prototypes. So what we're trying to do is we're trying to take that and then convert that into something that we know and we are more comfortable with. Not that that's a good idea or something, but that gives more insights about the language. So here is what we want to achieve. So I should be able to define a class like this. It's a class and then give all the functions or methods that you want to define. So I'll say a equal to new animal and then I say a dot eat and this function should get called. This is like the way we define classes in Java. Not just that, I want to extend this. I want to extend this class by, so once I have a base class I want to extend and create a new class from it. So what I want to do is when it's a bird equal to animal dot extend and define the new functions here. So when I say B dot fly, this function gets called. When I say B dot eat, the previous function defined in animal class should get called. So how to do this? Let's actually start with the basic thing. Sorry, any questions? So this first item, it's not really the complete solution. It doesn't support the inheritance yet, but let's see what it's doing. So what it does is it creates a new function. What the function does is it calls a constructor, the constructor calling with the name init. And it sets its prototype to the members who have passed. Let's actually see in an example what happens. So when you create a class like this, what happens is the animal, the prototype becomes the members that have passed as argument to this. That same function f that we're calling locally. So it's called locally f and that gets assigned to a variable animal here. But what happens when you actually create an object? So what it does is it takes an animal prototype and then assigns it as its underscore and square prototype. And then the constructor is adding a new property called name that would be dog. So this is how the object gets created. Now we have a classical way of class which still doesn't support inheritance, but you can create new objects. Actually, let's actually go one more level and then see if you can implement the inheritance, what we see in other languages. So that's a bit tricky. So let's actually borrow some ideas before we go further. So this is an idea from Douglas Crawford. Do you know who is Douglas Crawford? He created JSON, the JavaScript Object Rotation. So he's actually proposed a small function called object. What it does is it basically creates a chain. When you say an object O, it creates a new object with O in its prototype. Let's see how that works. When you say Y equal to object X, it creates Y with underscore and square prototype in X, pointing to X. When you say Z equal to object Y, Y becomes Z underscore and square prototype. So it actually makes this chain. So this is what we really need to support this kind of inheritance. Let's go back and look at the function again. So what it is doing is it's taking a function f and then setting its prototype. When you create a new object, its underscore and square prototype will be assigned to, will be set to its function's prototype. So this even works in the JavaScript engines where underscore and square prototype is not supported. I've just said O dot underscore and square prototype equal to, I mean, the new object dot underscore and square prototype equal to O. But that doesn't work in all the browsers. But this thing, this implementation works in all browsers. But with this tool now, we can actually implement the inheritance pattern. So this is the second attempt. So what we're doing here is we're adding a function extend. So other parts are exactly the same. But what extend does is it makes new objects, which is pointing to the prototype, and then copying all the methods here. Let's actually see that by an example. So when you say animal dot extend word, what happens is it creates a new object, such that its underscore and square prototype points to animal prototype, and then copies all its functions here. Now, when you create a new bird object, the bird object points to the bird's prototype, and that internal is pointing to the animal prototype. So with that object tool, we're able to construct these chains. And using the chains now, we have an inheritance pattern. So when you say b.eat or something, it comes here. It's not found here. So it travels to its parent, and then finds it here. That's it. So we have implemented a classical style inheritance in JavaScript. So that's all. So if you want to learn more, you can actually do some resources where you can go and look at them. And that's it. So let me know if you have any questions. Which slide? The classical inheritance, this one? This one or the previous one? This one is the next one. OK. So what I'm doing is I'm creating an object here. So the new object has a link to the original product. So F is a base class here. We're trying to create an extended class. So I'm creating a variable called newMembers, which has a link to the base class prototype. And I'm making this as its prototype. What do you mean by redefining an object? Can you please repeat the question? I couldn't get it. So what happens? So the question is, let's say I've defined an object with an assigned to variable. And then if you change it to some other object, what happens to the previous object? Yeah, that gets garbage collected. That gets thrown away. That depends on where you're running it. If you're running it in a browser, that becomes the window object. If you're running it in independent JavaScript environment like what I've shown here. So it has an object global. So here, x equals 1. I can actually say this dot x. That's still be 1. Sorry? This. That's just an object. It doesn't really. What is that? This is a modular JavaScript engine. So I mean, there are different JavaScript engines that you can use. One is the modular thing. Other is the V8 engine from Google. So you can install V8 or the modular JavaScript engine. I think it's called Spider Monkey or something. Sorry? OK, fine. In the first beginning examples. Yeah. So you were saying how is this becoming true in this case after changing that? Doesn't matter. No, actually, this is perfectly right. So what it's doing is maybe I should actually put that picture like the other ones. But so when you say F instance of a constructor, what it does is it takes constructor.prototype and then checks it. So now it doesn't really pass F here. All it really uses f.prototype. Once F instance of capital F, it takes capital F.prototype and then compares it to agnest. So when I'm passing G, what it's doing is it's taking G.prototype, which is same as f.prototype. So it's not inheritance. Oh, yeah. So it's not inheritance. It's just that I'm trying to say it really doesn't look at the function, what function it is. It only looks at functions prototype. Any other questions? Yeah. Then what happens is both of them will return false. Because the F is created before the change was made. So it points to a new prototype object. And it's got points to the old one. So both returns false. But if you create a new object, then it returns true. I didn't get. So what's one of the new operator? Yes. OK. Which one? Yeah? Yeah. Either do it or if you still have access to the variable that defines you. So the question is, is defining objects with private variables inside the closure is a good idea? Yes. I think it's a good idea. But I mean, that's a data encapsulation. So you actually don't want to expose some of these private implementation details. So you put them inside there. I think that's a good idea. I think most of jQuery implementation works that way. I don't know. I'm not really an expert. Done? Thank you.