{"id":109,"date":"2010-04-14T23:38:25","date_gmt":"2010-04-14T21:38:25","guid":{"rendered":"http:\/\/www.tapper-ware.net\/blog\/?p=109"},"modified":"2010-04-14T23:38:25","modified_gmt":"2010-04-14T21:38:25","slug":"a-pattern-for-javascript-oop-that-i-actually-use","status":"publish","type":"post","link":"https:\/\/www.tapper-ware.net\/blog\/a-pattern-for-javascript-oop-that-i-actually-use\/","title":{"rendered":"A pattern for Javascript OOP that I actually use"},"content":{"rendered":"<p>Apparently a few people were pretty irritated the last time I posted about what you can make Javascript do (+foo instead of foo() for calls) so today I thought I&#8217;d post about a pattern that I actually use regularly. Of course, as with any pattern there are good reasons not to use it. Most of all:complexity&#8230; for example you may not be able to make your favourite development environment understand it. Speed shouldn&#8217;t be an issue though: It adds one entry to the name lookup tree, but that shouldn&#8217;t even really be measurable.<\/p>\n<p>When you do OOP Javascript you&#8217;ll often want to add a lot of stuff to the prototype of a constructor. Often people use object notation to get around having to type Foo.prototype.bar=&#8230; over and over again. Problem is: This replaces the prototype, so if you&#8217;re using inheritance it won&#8217;t work. You&#8217;d overwrite the inherited prototype:<\/p>\n<pre>var BaseCtor=function(){};\r\n\r\nvar FailedInheritanceCtor=function(){};\r\nFailedInheritanceCtor.prototype=new BaseCtor;\r\nFailedInheritanceCtor.prototype={\r\n   foo:0,\r\n   bar:1\r\n};\r\n\r\nalert((new FailedInheritanceCtor) instanceof BaseCtor); \/\/false\r\n\r\nvar WorkingCtor=function(){};\r\nWorkingCtor.prototype=new BaseCtor;\r\nWorkingCtor.prototype.foo=0;\r\nWorkingCtor.prototype.bar=1;\r\n\r\nalert((new WorkingCtor) instanceof BaseCtor); \/\/true<\/pre>\n<p>So, you need to do assignments. Of course you could use a function to do them, but that&#8217;s one more unnecessary and ugly function call. Or you could use a temporary variable to point to the prototype&#8230; but unless you can use Javascript 1.7&#8217;s &#8220;let&#8221; statement that would mean contaminating the current scope. You could wrap it into an anonymous function, but that hardly improves readability.<\/p>\n<p>All of this can be avoided by using the poor man&#8217;s &#8220;let&#8221; (or poor browser&#8217;s: your choice): with()<br \/>\nWith pushes an object into the name lookup tree&#8230; the nice thing is that this object can be created right inside that statement<\/p>\n<pre>with({hello:\"world\"})\r\n   alert(hello); \/\/world<\/pre>\n<p>And we can do the same stupid trick with the prototype property:<\/p>\n<pre>var BaseCtor=function(){};\r\n\r\nvar WorkingCtor=function(){};\r\nWorkingCtor.prototype=new BaseCtor;\r\nwith({_:WorkingCtor.prototype}){\r\n   _.foo=0;\r\n   _.bar=1;\r\n}<\/pre>\n<p>or like this if you want it more compact (I never do that though):<\/p>\n<pre>var BaseCtor=function(){};\r\n\r\nvar WorkingCtor=function(){};\r\nwith({_:WorkingCtor.prototype=new BaseCtor}){\r\n   _.foo=0;\r\n   _.bar=1;\r\n}<\/pre>\n<p>There. simple. I usually combine it with a variable _ inside the methods to get to this, but that may feel wrong to you.<\/p>\n<pre>var BaseCtor=function(){\r\n   var _=this;\r\n};\r\n\r\nvar WorkingCtor=function(argFoo){\r\n   var _=this;\r\n\r\n   _.foo=argFoo;\r\n};\r\nWorkingCtor.prototype=new BaseCtor;\r\nwith({_:WorkingCtor.prototype}){\r\n   _.foo=0;\r\n   _.bar=function(argFoo){\r\n      var _=this;\r\n\r\n      alert(_.foo);\r\n   };\r\n}\r\n\r\n(new WorkingCtor(1)).bar(); \/\/1\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Apparently a few people were pretty irritated the last time I posted about what you can make Javascript do (+foo instead of foo() for calls) so today I thought I&#8217;d post about a pattern that I actually use regularly. Of course, as with any pattern there are good reasons not to use it. Most of &hellip; <a href=\"https:\/\/www.tapper-ware.net\/blog\/a-pattern-for-javascript-oop-that-i-actually-use\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">A pattern for Javascript OOP that I actually use<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.tapper-ware.net\/blog\/wp-json\/wp\/v2\/posts\/109"}],"collection":[{"href":"https:\/\/www.tapper-ware.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tapper-ware.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tapper-ware.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tapper-ware.net\/blog\/wp-json\/wp\/v2\/comments?post=109"}],"version-history":[{"count":1,"href":"https:\/\/www.tapper-ware.net\/blog\/wp-json\/wp\/v2\/posts\/109\/revisions"}],"predecessor-version":[{"id":110,"href":"https:\/\/www.tapper-ware.net\/blog\/wp-json\/wp\/v2\/posts\/109\/revisions\/110"}],"wp:attachment":[{"href":"https:\/\/www.tapper-ware.net\/blog\/wp-json\/wp\/v2\/media?parent=109"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tapper-ware.net\/blog\/wp-json\/wp\/v2\/categories?post=109"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tapper-ware.net\/blog\/wp-json\/wp\/v2\/tags?post=109"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}