{"id":280,"date":"2008-01-24T22:22:35","date_gmt":"2008-01-25T03:22:35","guid":{"rendered":"http:\/\/unitstep.net\/blog\/2008\/01\/24\/javascript-and-inheritance\/"},"modified":"2011-05-28T09:40:55","modified_gmt":"2011-05-28T14:40:55","slug":"javascript-and-inheritance","status":"publish","type":"post","link":"https:\/\/unitstep.net\/blog\/2008\/01\/24\/javascript-and-inheritance\/","title":{"rendered":"JavaScript and inheritance"},"content":{"rendered":"
JavaScript has a complicated history. The name itself<\/a> seems to indicate a relationship to Java, when in fact, the two languages share little in common except for a common syntax relationship by way of C. Add to this the myriad of browser incompatibilities and numerous examples of bad usage, and you have what is perhaps the world’s least understood popular programming language. (I had to add the ‘popular’ qualifier, since I am sure there are some esoteric languages out there that only a handful of people know)<\/p>\n This is why inheritance in JavaScript is probably one of the least understood concepts. While languages like Java have well-defined constructs for inheritance, the topic is of less importance with JavaScript. In many situations, you’ll never have to deal with these aspects when programming in JavaScript, simply because it isn’t required for a lot of client side scripts. However, for larger-scale web applications, applying object-oriented principles to your code may make it easier to design, improve and maintain.<\/p>\n There have been many<\/a> articles<\/a> written<\/a> about inheritance in JavaScript and how it can and should be done. You really don’t need to read mine to gain an understanding. Rather, I’m just going to write about what I’ve learned, the process I went through and the experience I’ve gained along the way. <\/p>\n <\/p>\n If you come from a Java background, you’ll be no stranger to the JavaScript also has a Consider the following example.<\/p>\n If you’re familiar with Java or JavaScript, this example is fairly straightforward. In the prototype-based JavaScript, functions can serve as object constructors<\/a> in somewhat the same manner as a constructor in Java. However, Before we dive into the details, I’ll explain the concepts of a prototype-based language as it applies to JavaScript. I mentioned above that JavaScript does not use classes like Java does. This basically means that new objects are not created from instantiation of classes, but rather inherit from existing objects. Thus, there is no “class hierarchy” but rather just an object hierarchy. <\/p>\n In JavaScript, all objects are descended from the built-in This example is identical to the first one, except for the lines that are emphasized. Here, I’ve set the In JavaScript, the Thus, the code in When you call a property on Where things get confusing is because of how the Suppose you created multiple objects from the This adds another method to all I mentioned inheritance above but with just one type definition, the principles weren’t too clear. Suppose we decided to extend our Let’s break down what’s going on here.<\/p>\n JavaScript provides two special operators for dealing with types and objects. One is called The The In the above code, it is clear that I hope I haven’t said “foo” one too many times for you.<\/p>\n More information about I hope this has helped you to understand the nature of JavaScript’s built-in inheritance features. I know I found it very convoluted at first, coming from a class-inheritance background. I read everything I could find on the subject, and I believe it’s made me a better JavaScript programmer by understanding some of the “inner workings” of the language. I encourage you to check out some of the references I’ve provided below.<\/p>\n JavaScript has a complicated history. The name itself seems to indicate a relationship to Java, when in fact, the two languages share little in common except for a common syntax relationship by way of C. Add to this the myriad of browser incompatibilities and numerous examples of bad usage, and you have what is perhaps […]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[64,206,4,137,205],"tags":[],"_links":{"self":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/280"}],"collection":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/comments?post=280"}],"version-history":[{"count":3,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/280\/revisions"}],"predecessor-version":[{"id":1287,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/posts\/280\/revisions\/1287"}],"wp:attachment":[{"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/media?parent=280"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/categories?post=280"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unitstep.net\/wp-json\/wp\/v2\/tags?post=280"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}It’s all new(s) to me<\/h3>\n
new<\/code> keyword. Using it allows you to instantiate a new instance of an object from its class by calling its constructor. The keyword also makes a lot of sense, since you’re creating a ‘new’ object.<\/p>\n
new<\/code> keyword, but it doesn’t do quite the same thing as its Java counterpart, though at first the effects might seem similar. This is one of the main reasons why JavaScript inheritance tends to be poorly understood. <\/p>\n
function Foo(name)\r\n{\r\n this.name = name;\r\n}\r\n\r\nvar fooObject = new Foo('I am foo');<\/code><\/pre>\n
Foo<\/code> in the above example is not a class, since classes do not exist in JavaScript. So, if
Foo<\/code> is not a class, what exactly happens when the statement
var fooObject = new Foo('I am foo')<\/code> is executed?<\/p>\n
Taking a step back<\/h3>\n
Object<\/code><\/a> type. This is similar to how all Java classes implicitly have the Object class as a superclass. In JavaScript, instead of extending classes, you can inherit by manipulating the
prototype<\/code> property on a type; that is, the
prototype<\/code> property on the function you are using to create an object. Let’s see some code to straighten things out.<\/p>\n
function Foo(name)\r\n{\r\n this.name = name;\r\n}\r\nFoo.prototype.getName = function()\r\n{\r\n alert(this.name);\r\n}<\/strong>\r\n\r\nvar fooObject = new Foo('I am foo');\r\nfooObject.getName(); \/\/ Will alert with 'I am foo'<\/strong><\/code><\/pre>\n
getName<\/code> property on the
prototype<\/code> property of
Foo<\/code> equal to a reference to a Function object. This is effectively the same as defining a method for a class, since any object created from that type can call the method
getName()<\/code> on itself to return the proper value. But what exactly is happening, and what’s the deal with the
prototype<\/code> property?<\/p>\n
More new(s)<\/h3>\n
new<\/code> keyword actually accomplishes a few things. When you execute an expression such as
var fooObject = new Foo('I am foo')<\/code>, here’s exactly what happens.<\/p>\n
\n
new Object()<\/code>, using JavaScript’s built in Object type<\/a>.\n<\/li>\n
Foo()<\/code>, is then called with the
this<\/code> keyword set to reference the newly-created object. The parameters supplied are also passed to the constructor function, in this case, the string “I am foo”. If you’re familiar with context<\/a>, this is equivalent to:<\/p>\n
var fooObject = new Object();\r\nFoo.call(fooObject, 'I am foo');<\/code><\/pre>\n
Foo()<\/code> sets a property called
name<\/code> equal to the supplied string. Up to this point, things are the same as if you had created a new object and then manually set the
name<\/code> property yourself. The next step is where things change.\n<\/li>\n
__proto__<\/code> equal to the value of
Foo.prototype<\/code>. This is how the new object inherits from the old one.<\/p>\n
fooObject<\/code> now, JavaScript will first check to see if the object has a local value for it. In this case, the only local property is
name<\/code>. (Besides the internal and implicitly set
__proto__<\/code> property) However, if it does not exist locally, it will check to see if the property exists under the object referenced by the
__proto__<\/code> property. In this case, the
getName()<\/code> method exists under here.\n<\/li>\n<\/ol>\n
new<\/code> keyword is used. Perhaps the designers of JavaScript wanted to use a keyword familiar to Java programmers so as to ease the transition to a new language that sounded so similar. While it accomplishes a similar goal and for the most part you can consider the action to be almost the same, the use of the
new<\/code> keyword conceals the true meaning of prototype-based inheritance in JavaScript. This ends up causing more confusion when you start digging into code.<\/p>\n
We’re all the same<\/h3>\n
Foo()<\/code> constructor, called
fooObject1<\/code>,
fooObject2<\/code> and
fooObject3<\/code>, In one fell swoop, you could add a new method to all of these objects without having to recreate them. This is because of the
prototype<\/code> property. Because each object contains a reference to
Foo.prototype<\/code>, adding a new method here will allow all objects access to it. For example:<\/p>\n
Foo.prototype.yellName = function()\r\n{\r\n alert(this.name.toUpperCase());\r\n}\r\nvar fooObject3 = new Foo('I am Foo 3!');\r\nfooObject3.yellName(); \/\/ alerts 'I AM FOO 3!'<\/code><\/pre>\n
Foo<\/code>-constructed objects allowing them to “yell” their names.<\/p>\n
Extending Types<\/h3>\n
Foo<\/code> “class” – how exactly would this work? First, you need to define the child type and then set its
prototype<\/code> value to a new object of the parent type. An example:<\/p>\n
function FooChild(childName)\r\n{\r\n Foo.call(this, 'I am a child of Foo and my name is ' + childName);\r\n}\r\nFooChild.prototype = new Foo('');\r\n\r\nvar fooChildObject = new FooChild('Barbar');\r\nfooChildObject.getName(); \/\/ Will alert with 'I am a child of Foo and my name is Barbar'<\/code><\/pre>\n
\n
FooChild<\/code>. In it, we
call<\/code> the parent constructor function with the context set to the current object. This allows the
name<\/code> property to be set on the object during creation since that’s what the parent does.\n<\/li>\n
prototype<\/code> property equal to a new object that’s an instance of
Foo<\/code>. This is what allows all of the child objects to have access to the parent’s properties, such as the
getName()<\/code> method. Coming from the Java world, this would be roughly equivalent to the
extends<\/code> keyword, when defining a class that inherits from another.\n<\/li>\n<\/ol>\n
A few more details<\/h3>\n
instanceof<\/code> and the other is
typeof<\/code>. The latter,
typeof<\/code>, is less useful since it only deals with built-in JavaScript types.<\/p>\n
typeof<\/code> operator returns the current variable’s type, but is limited to predefined types. For example,
typeof fooChildObject<\/code> or
typeof fooObject<\/code> both return a string with the contents of “object”. Thus, differentiating between the two is impossible. More information can be found at the Mozilla Developer Center<\/a>.<\/p>\n
instanceof<\/code> operator is more interesting. It takes two arguments and tests whether the first is an instance of the second. (I guess I didn’t need to explain that) For example:<\/p>\n
function Foo(name)\r\n{\r\n this.name = name;\r\n}\r\nFoo.prototype.getName = function()\r\n{\r\n alert(this.name);\r\n}\r\n\r\nfunction FooChild(childName)\r\n{\r\n Foo.call(this, 'I am a child of Foo and my name is ' + childName);\r\n}\r\nFooChild.prototype = new Foo('');\r\n\r\nvar fooObject = new Foo('I am foo');\r\nvar fooChildObject = new FooChild('Barbar');\r\n\r\nalert(fooChildObject instanceof Foo); \/\/ true\r\nalert(fooObject instanceof Foo); \/\/ true\r\nalert(fooChildObject instanceof FooChild); \/\/ true\r\nalert(fooObject instanceof FooChild); \/\/ false;<\/code><\/pre>\n
fooChildObject<\/code> is an instance of
FooChild<\/code>, and
fooObject<\/code>is an instance of
Foo<\/code>. However,
fooChildObject<\/code> is also<\/strong> an instance of
Foo<\/code>, since its type was inherited from it through the
prototype<\/code> property. However,
fooObject<\/code> is not<\/strong> an instance of
FooChild<\/code> since that type is a child of
Foo<\/code>.<\/p>\n
instanceof<\/code> is again available<\/a> from the excellent Mozilla Developer Center.<\/p>\n
Concluding remarks<\/h3>\n
References<\/h3>\n
\n