{"id":975,"date":"2022-08-30T15:10:18","date_gmt":"2022-08-30T15:10:18","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/11\/09\/how-to-inherit-correctly-in-javascript-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:10:18","modified_gmt":"2022-08-30T15:10:18","slug":"how-to-inherit-correctly-in-javascript-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/how-to-inherit-correctly-in-javascript-collection-of-common-programming-errors\/","title":{"rendered":"How to inherit correctly in javascript?-Collection of common programming errors"},"content":{"rendered":"<p>My understanding is that &#8220;hasOwnProperty&#8221; returns true if the object has a given member without check the prototype chain. But when I inherit fro other object, I see all members in the last object itself.<\/p>\n<p>Consider the following example:<\/p>\n<pre><code>var Object1 = function (param) {\n    this.prop1 = \"p1 \" + param;\n    this.prop2 = \"p2 \" + param;\n};\n\nvar Object2 = function (param) {\n    Object1.apply(this, arguments);\n    this.prop3 = 'p3' + param;\n};\n\nObject2.prototype = new Object1();\n\nvar b = new Object2('this is Object 2');\n\nfor (var v in b)\n    print(v + \": \" + b[v] + (b.hasOwnProperty(v)?' (own)':' (inherited)'));\n<\/code><\/pre>\n<p>This code prints:<\/p>\n<pre><code>--prop1: p1 this is Object 2 (own)\n--prop2: p2 this is Object 2 (own)\n--prop3: p3this is Object 2 (own)\n<\/code><\/pre>\n<p>If I take a look on the debugger I see:<\/p>\n<pre><code>b\n  Object2\n    prop1: \"p1 this is Object 2\"\n    prop2: \"p2 this is Object 2\"\n    prop3: \"p3this is Object 2\"\n    __proto__: Object1\n<\/code><\/pre>\n<p>But, id I remove the <code>apply<\/code> line, all makes more sense, but base object it is not initialized:<\/p>\n<pre><code>--prop3: p3this is Object 2 (own)\n--prop1: p1 undefined (inherited)\n--prop2: p2 undefined (inherited)\n<\/code><\/pre>\n<p>Now I see in the debugger:<\/p>\n<pre><code>b\n  Object2\n    prop3: \"p3this is Object 2\"\n    __proto__: Object1\n      prop1: \"p1 undefined\"\n      prop2: \"p2 undefined\"\n      __proto__: Object\n<\/code><\/pre>\n<p>As far as I know, <code>apply<\/code> it&#8217;s like &#8230; execute the super class constructor, so super members are initialized correctly, but apparently that changes the shape of the child object.<\/p>\n<p>Why is this happening? What is the correct way -or at least the less messy- to inherit in JS?<\/p>\n<p>I am taking a look to some information about it, and apparently each developer has different feelings about how to do it.<\/p>\n<p>Regards.<\/p>\n<ol>\n<li>\n<p><code>apply<\/code> is not at all like executing the super class constructor. As a construct, it executes <em>any<\/em> function <strong>in the scope of the first provided argument<\/strong>. When you pass <code>this<\/code> to your <code>Object1<\/code> function (which you execute as a function, not as a constructor), you are passing through the scope in which your second function (<code>Object2<\/code>) is being executed.<\/p>\n<p>To see what&#8217;s happening, try executing <code>Object1(\"param\")<\/code> <strong>without<\/strong> <code>new<\/code>:<\/p>\n<pre><code>Object1(\"test\");\n<\/code><\/pre>\n<p>When we execute <code>new Object1(\"test\")<\/code> we get back an object that looks like this:<\/p>\n<pre><code>Object { prop1=\"p1 test\", prop2=\"p2 test\"}\n<\/code><\/pre>\n<p>But when we execute <code>Object1(\"test\")<\/code> we get back <code>undefined<\/code> &#8230; and on the object equal to <code>this<\/code> (most likely <code>window<\/code> in the case of browser JavaScript) we find two new variables &#8230; <code>prop1<\/code> and <code>prop2<\/code>.<\/p>\n<p>The key here is that:<\/p>\n<pre><code>Object1(\"param\") !== new Object1(\"param\");\n<\/code><\/pre>\n<p>The first version (<code>Object1(\"param\")<\/code>) executes a function (<code>Object1<\/code>) in some <em>already existing<\/em> scope (in browser JavaScript the most common scope is the top-level scope where <code>this === window<\/code>.) This is the way you are invoking <code>Object1<\/code> when you call <code>Object1.apply(this)<\/code>.<\/p>\n<p>The second version (<code>new Object1(\"param\")<\/code>) executes a function <strong>as a constructor<\/strong> &#8211; that is, it creates a <strong>new<\/strong> object and sets <code>this<\/code> to be that new object. If we were to use the same <code>apply<\/code> function to demonstrate this we would write <code>Object1.apply({})<\/code>;<\/p>\n<p>For one of the most definitive answers I have ever seen on the subject of how to do OOP-like programming <em>right<\/em> in a JavaScript environment, see Bobince&#8217;s answer to this question.<\/p>\n<\/li>\n<\/ol>\n<p id=\"rop\"><small>Originally posted 2013-11-09 23:09:22. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>My understanding is that &#8220;hasOwnProperty&#8221; returns true if the object has a given member without check the prototype chain. But when I inherit fro other object, I see all members in the last object itself. Consider the following example: var Object1 = function (param) { this.prop1 = &#8220;p1 &#8221; + param; this.prop2 = &#8220;p2 &#8221; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-975","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/975","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=975"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/975\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=975"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=975"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=975"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}