{"id":7633,"date":"2019-11-17T18:36:45","date_gmt":"2019-11-17T18:36:45","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=7633"},"modified":"2019-11-18T11:16:25","modified_gmt":"2019-11-18T11:16:25","slug":"this-is-not-the-this-you-might-expect","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/this-is-not-the-this-you-might-expect\/","title":{"rendered":"this is not the this you might expect"},"content":{"rendered":"<p><strong>this<\/strong> within TypeScript\/JavaScript is not the same as you&#8217;re used to if you come from an OO language such as C#, Java, C++ or the likes.<\/p>\n<p>Within these languages <em>this<\/em> is the internal reference to the instance of the object your methods are members of, within TypeScript\/JavaScript <em>this<\/em> depends upon the current &#8220;execution context&#8221;. This is one of the reasons when writing code for event handler in React (for example) we need code such as<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nthis.handleClick = this.handleClick.bind(this);\r\n<\/pre>\n<p>In JavaScript the runtime maintains a stack of execution contexts. As such functions (not part of a class) have access to <em>this<\/em> which will point to the global object, which in a browser would be <em>window<\/em> and via node is a special global object.<\/p>\n<p>Yes for those coming from an OO language it would seem odd that functions outside of classes have access to <em>this<\/em>.<\/p>\n<p>For example, running <em>node index.js<\/em> on this index.js file, will display <em>Object [global]<\/em>, however if we add <em>&#8216;use strict&#8217;;<\/em> to the start of index.js <em>this<\/em> will be undefined.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nfunction fn() {\r\n    console.log(this);\r\n}\r\n\r\nfn();\r\n<\/pre>\n<p>If we now create a JavaScript class (either ECMAScript 2015) for example<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass MyClass {\r\n    constructor(arg1, arg2) {\r\n        this.arg1 = arg1;\r\n        this.arg2 = arg2;\r\n    }\r\n}\r\n<\/pre>\n<p>We&#8217;ll find that <em>this<\/em> no longer references the global object, instead the <em>new<\/em> keyword (when we create an instance of this class) causes the JavaScript runtime to create a new object assigned to <em>this<\/em> specific to the class. Hence if you <em>console.log(this)<\/em> from the class you&#8217;ll see <em>this<\/em> within a new execution context, scoped to the class.<\/p>\n<p>Let&#8217;s return to our class and add a new method, so the MyClass code should look like this<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass MyClass {\r\n    constructor(arg1, arg2) {\r\n        this.arg1 = arg1;\r\n        this.arg2 = arg2;\r\n    }\r\n\r\n    output() {\r\n        console.log(this);\r\n    }\r\n}\r\n<\/pre>\n<p>if we now execute the following<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nconst mc = new MyClass(&quot;Scooby&quot;, &quot;Doo&quot;);\r\nmc.output();\r\n<\/pre>\n<p>as you&#8217;d expect, the out function logs the MyClass instance (shown below) to the console.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nMyClass { arg1: 'Scooby', arg2: 'Doo' }\r\n<\/pre>\n<p>If, however we instead have the following code<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nconst mc = new MyClass(&quot;Scooby&quot;, &quot;Doo&quot;);\r\nconst fn = mc.output;\r\nfn();\r\n<\/pre>\n<p>the fn() call, which is ultimately just a call mc.output() will output <em>undefined<\/em> for this. What&#8217;s happening is we&#8217;re actually executing the function outside of the class and <em>this<\/em> (in node) is now undefined.<\/p>\n<p>We might think that C# etc. is wrapping <em>this<\/em> in a closure or the likes, whereas JavaScript is not. So how do we &#8220;bind&#8221; <em>this<\/em> to the new output function &#8211; the clue is in the use of the work &#8220;bind&#8221;. Adding the following to the constructor, now binds the <em>this<\/em> from the class to the method and now calling fn() will output the MyClass object.<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nthis.output = this.output.bind(this);\r\n<\/pre>\n<p>Interestingly, as JavaScript function have a bind, call and apply functions on them, we could actually bind the function to a totally different instance of an object, hence if we created a totally different class and then bind the function to it, the output will display the new object, i.e. <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass PointlessClass  {\r\n}\r\n<\/pre>\n<p>and now in the MyClass constructor we have<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nthis.output = this.output.bind(new PointlessClass());\r\n<\/pre>\n<p>Then, using either method of calling the output method or assigning to fn and calling outside of the class, we&#8217;ll get PointlessClass {} logged to the console.<\/p>\n<p>If we go back to the code <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nconst mc = new MyClass(&quot;Scooby&quot;, &quot;Doo&quot;);\r\nconst fn = mc.output;\r\nfn();\r\n<\/pre>\n<p>We can change this to bind (instead of the constructor) if we so wished, for example<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nconst mc = new MyClass(&quot;Scooby&quot;, &quot;Doo&quot;);\r\nconst fn = mc.output.bind(mc);\r\nfn();\r\n<\/pre>\n<p>The above will now output the instance of MyClass as it&#8217;s <em>this<\/em>. <\/p>\n<p>As previously mentioned a function can <em>bind<\/em>, <em>call<\/em> and <em>apply<\/em>. So bind sets the <em>this<\/em> on the method and every time the method is called it&#8217;s bound to MyClass. Call executes a method against the supplied <em>this<\/em> only for that single call as does apply i.e. <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nconst fn = mc.output;\r\n\r\nfn.call(mc);\r\nfn();\r\n<\/pre>\n<p>the fn.call will output an instance of MyClass but the fn() will again output undefined (or the global execution context).<\/p>\n<p>I mentioned call and apply did the same things, so what&#8217;s the difference? The difference is in the way arguments are passed to these functions, call takes an array of arguments whereas apply takes a set, other than that they do the same thing, immediately execute the method against the supplied <em>this<\/em>.<\/p>\n<p>Finally, arrow (also known as fat arrow) functions are part ECMAScript 2015 and they are automatically bound to this, let&#8217;s assume we change our MyClass to <\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nclass MyClass {\r\n    constructor(arg1, arg2) {\r\n        this.arg1 = arg1;\r\n        this.arg2 = arg2;\r\n        this.output = () =&gt; console.log(this);\r\n    }\r\n}\r\n<\/pre>\n<p>Now if we use this function like we did earlier, which if you recall output undefined for <em>this<\/em><\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nconst fn = mc.output;\r\nfn();\r\n<\/pre>\n<p>with the arrow function we found <em>this<\/em> was set to the instance of MyClass it was declared within. So basically it appears to be already bound, in reality it&#8217;s better to think of the arrow functions as inheriting the <em>this<\/em> because unlike non arrow methods, we cannot rebind it&#8217;s <em>this<\/em> reference. For example, the following will still output the MyClass instance, not the new PointlessClass that we&#8217;ve attempt to bind to<\/p>\n<p>const fn = mc.output.bind(new PointlessClass());<br \/>\nfn();<br \/>\n[\/code[<\/p>\n","protected":false},"excerpt":{"rendered":"<p>this within TypeScript\/JavaScript is not the same as you&#8217;re used to if you come from an OO language such as C#, Java, C++ or the likes. Within these languages this is the internal reference to the instance of the object your methods are members of, within TypeScript\/JavaScript this depends upon the current &#8220;execution context&#8221;. This [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[45],"tags":[],"class_list":["post-7633","post","type-post","status-publish","format-standard","hentry","category-javascript"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7633","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=7633"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7633\/revisions"}],"predecessor-version":[{"id":7701,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7633\/revisions\/7701"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=7633"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=7633"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=7633"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}