{"id":19240,"date":"2018-08-29T11:30:58","date_gmt":"2018-08-29T11:30:58","guid":{"rendered":"https:\/\/www.heartinternet.uk\/blog\/?p=19240"},"modified":"2018-08-29T11:30:58","modified_gmt":"2018-08-29T11:30:58","slug":"3-features-that-could-change-the-future-of-javascript","status":"publish","type":"post","link":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/","title":{"rendered":"3 features that could change the future of JavaScript"},"content":{"rendered":"<p>Do you want to discover the next exciting JavaScript features that you didn\u2019t even know you needed? Let me show you three proposals that may change the way you write code the same way the <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Operators\/Spread_syntax\">spread operator<\/a> did.\n<\/p>\n<p>\nHowever, here\u2019s a small disclaimer:\n<\/p>\n<p>\nAll of these features are under development and discussion. The goal here is to add some hype around those features and create awareness of the hard work that TC39 is doing to find consensus, fix all the syntax and semantics and have them shipped with the next releases of ECMAScript. If you have any concerns, comments or desire to express your support, please go to the <a href=\"https:\/\/github.com\/tc39\/proposals\">TC39 proposals repository<\/a>, add a star to the feature you would like to support, open an issue to voice your concerns and get involved.\n<\/p>\n<p>\nBut before I present the first proposal, I want to ask a simple (but tricky) question:<\/p>\n<h3>What is \u2018this\u2019?<\/h3>\n<p>In ECMAScript, <code>this<\/code> has a different semantic than <code>this<\/code> in many other programming languages, where <code>this<\/code> often refers to the lexical scope. Let\u2019s break this behaviour down into small examples:<\/p>\n<h4>\u2018This\u2019 in the global scope<\/h4>\n<p>What is the value of <code>this<\/code> in this example?<\/p>\n<pre><code>console.info(this);<\/code><\/pre>\n<p>At the global scope, <code>this<\/code> refers to the global object, like the <strong>window<\/strong> in the browser, <strong>self<\/strong> on web workers and the <strong>module.exports<\/strong> object in NodeJS.<\/p>\n<h4>\u2018This\u2019 in the function scope<\/h4>\n<p>At the function scope, this behaves depending on how the function is called, and this aspect makes it tricky to predict its value. We can understand it better by checking the following example:<\/p>\n<pre><code>&lt;button id=\"button\"&gt;\ud83d\udc31 \ud83d\udc3e&lt;\/button&gt;\n&lt;script&gt;\n  class MeowctComponent {\n    constructor() {\n      this.paw = document.getElementById('button');\n    }\n\n    meow() {\n      console.info('\ud83d\udc31 on this: ', this.paw);\n    }\n  }\n\n  const cat = new MeowctComponent();\n  cat.paw.addEventListener('click', cat.meow);\n&lt;\/script&gt;<\/code><\/pre>\n<p>In the example above, I created a <code>MeowctComponent<\/code>, which has only one property <code>paw<\/code> that points to the button element and one method called <code>meow<\/code> that should print the paw instance property into the console.\n<\/p>\n<p>\nThe tricky part is that the meow method is executed only when the button is clicked, and because of that, this carries a button tag as context, and since the button tag does not have any paw property, it logs the <strong>undefined<\/strong> value into the console. Tricky, isn\u2019t it?\n<\/p>\n<p>\nTo fix this specific behaviour we can leverage the <code>Function.prototype.bind()<\/code> method to explicitly bind this to the cat instance, like in the following example:<\/p>\n<pre><code>&lt;button id=\"button\"&gt;Meow&lt;\/button&gt;\n&lt;script&gt;\nclass MeowctComponent {\nconstructor() {\nthis.paw = document.getElementById('button');\n}\n\nmeow() {\nconsole.info('\ud83d\udc31 on this: ', this.paw);\n}\n}\n\nconst cat = new MeowctComponent();\ncat.paw.addEventListener('click', cat.meow.bind(cat));\n&lt;\/script&gt;<\/code><\/pre>\n<p>The method <code>.bind()<\/code> returns a permanently bound function to the first given parameter, which is the context. Now, because we bound the <code>cat.meow<\/code> method to the <code>cat<\/code> instance, <code>this.paw<\/code> inside the meow method correctly points to the <em>button element<\/em>.\n<\/p>\n<p>\nAs an alternative to the <code>Function.prototype.bind()<\/code> method, we can use the arrow function to achieve the same result. It keeps the value of the lexical <code>this<\/code> of the surrounding context and dispenses the need to bind the context explicitly, like in the next example:<\/p>\n<pre><code>&lt;button id=\"button\"&gt;\ud83d\udc31 Meow&lt;\/button&gt;\n&lt;script&gt;\nclass MeowctComponent {\nconstructor() {\nthis.paw = document.getElementById('button');\n}\n\nmeow() {\nconsole.info('\ud83d\udc31 on this: ', this.paw);\n}\n}\n\nconst cat = new MeowctComponent();\ncat.paw.addEventListener('click', () =&gt; cat.meow());\n&lt;\/script&gt;<\/code><\/pre>\n<p>Although arrow functions solve the majority of use cases where we need to bind the lexical <code>this<\/code> explicitly, we still have two use cases for which the use of the explicit bind is needed.<\/p>\n<h4>Calling a known function using <code>this<\/code> to provide context:<\/h4>\n<pre><code>let hasOwnProp = Object.prototype.hasOwnProperty;\nlet obj = Object.create(null);\n\nobj.hasOwnProperty('x') \/\/ Type Error...\n\nhasOwnProp.call(obj, \"x\"); \/\/false\n\nobj.x = 100;\n\nhasOwnProp.call(obj, \"x\"); \/\/ true<\/code><\/pre>\n<p>Let&#8217;s suppose for any reason we have this <code>obj<\/code> object that doesn&#8217;t extend <code>Object.prototype<\/code> but we need to check if <code>obj<\/code> has an <code>x<\/code> property by using the <code>hasOwnProperty<\/code> method from <code>Object.prototype<\/code>. To achieve that, we have to use the call method and explicitly pass <code>obj<\/code> as the first parameter to make it work as expected, which appears not to be so idiomatic.<\/p>\n<h4>Extracting a method<\/h4>\n<p>The second case can be spotted when we need to extract a method from an object like in our <code>MeowctComponent<\/code> example:<\/p>\n<pre><code>&lt;button id=\"button\"&gt;\ud83d\udc31 \ud83d\udc3e&lt;\/button&gt;\n&lt;script&gt;\nclass MeowctComponent {\nconstructor() {\nthis.paw = document.getElementById('button');\n}\n\nmeow() {\nconsole.info('\ud83d\udc31 on this: ', this.paw);\n}\n}\n\nconst cat = new MeowctComponent();\ncat.paw.addEventListener('click', cat.meow.bind(cat));\n&lt;\/script&gt;<\/code><\/pre>\n<p>These use cases are the perfect hook for presenting the first TC39 proposal.<\/p>\n<h3>The Bind Operator <code>::<\/code><\/h3>\n<p>The <strong>Bind operator<\/strong> consists of an introduction of a new operator <code>::<\/code> (double colon), which acts as syntax sugar for the previous two use cases. It comes in two formats: <strong>binary<\/strong> and <strong>unary<\/strong>.\n<\/p>\n<p>\nIn its binary form, the bind operator creates a function with its left side bound to <strong>this<\/strong> of the right side, like in the following example:<\/p>\n<pre><code>let hasOwnProp = Object.prototype.hasOwnProperty;\nlet obj = Object.create(null);\n\nobj.hasOwnProperty('x') \/\/ Type Error...\n\nobj::hasOwnProp(\"x\"); \/\/false\n\nobj.x = 100;\n\nobj::hasOwnProp(\"x\"); \/\/ true<\/code><\/pre>\n<p>That looks more natural, doesn\u2019t it?\n<\/p>\n<p>\nIn its unary form, the operator creates a function bound to the base of the provided reference as a value for <strong>this<\/strong> variable, like in the following example:<\/p>\n<pre><code>...\ncat.paw.addEventListener('click', ::cat.meow);\n\/\/ which desugars to\ncat.paw.addEventListener('click', cat.meow.bind(cat));\n...<\/code><\/pre>\n<p>What\u2019s so cool about the bind operator is the fact that it opens up new opportunities for creating virtual methods, as in this example of lib for iterable.<\/p>\n<pre><code>import { map, takeWhile, forEach } from \"iterlib\";\n\ngetPlayers()\n::map(x =&gt; x.character())\n::takeWhile(x =&gt; x.strength &gt; 100)\n::forEach(x =&gt; console.log(x));<\/code><\/pre>\n<p>It\u2019s super useful because the developer doesn\u2019t need to download the whole lib to do small stuff, which reduces the impact on the bundle size of production applications. Besides, it makes those kinds of libs easier to extend.\n<\/p>\n<p>\nThe author of the bind operator is Kevin Smith, and <a href=\"https:\/\/github.com\/tc39\/proposal-bind-operator\">this proposal is in Stage 0<\/a>.\n<\/p>\n<h3>The Pipeline Operator<\/h3>\n<p>We just explored the benefits of having a virtual method for composition. However, with the bind operator, we have to rely on the <code>this<\/code> variable to be bound to a particular function to be able to compose behaviour. Some use cases require us to not rely on binding <code>this<\/code> to compose functionalities. Before introducing the next proposal, it\u2019s a good idea to dig a little more into this use case.\n<\/p>\n<p>\nSo let&#8217;s imagine we have a request to create a function that sanitises a text entry from the user, then transforms all number symbols into their textual representation. How do we usually do this?<\/p>\n<pre><code>const userInput = document.getElementById('user-input').value;\nconst sanitizedInput = sanitize(userInput);\nconst textualizedNumberInput = textualizeNumbers(sanitizedInput);\nconsole.log(textualizedNumberInput);<\/code><\/pre>\n<p>One possible solution could be achieved by the code above. It\u2019s pretty standard, but to make it easy to read, we end up creating a lot of intermediary variables. You might want to improve it by just removing those variables. Let&#8217;s see what this would look like.<\/p>\n<pre><code>console.log(\ntextualizeNumbers(\nsanitize(\ndocument.getElementById('user-input').value\n)\n)\n);<\/code><\/pre>\n<p>It seems that the snippet above can lead to messy code. To understand the data flow, the developer needs to look from the middle back up to the top, which doesn\u2019t feel natural. Is there a better way to compose these functions without ending up with a deeply nested composition or the verbosity of intermediary variables? Enter the next proposal, the <strong>Pipeline Operator<\/strong>!<\/p>\n<h4>The pipeline operator minimal proposal<\/h4>\n<p>The Pipeline operator is syntax sugar for the use cases we presented above. It creates a way to streamline a chain of functions in a readable and functional manner. It\u2019s backward compatible and provides an alternative for extending built-in prototypes. To illustrate how it can simplify the codebase, let\u2019s see how the previous example could look with the pipeline operator.<\/p>\n<pre><code>document.getElementById('user-input').value\n|&gt; sanitize\n|&gt; textualizeNumbers\n|&gt; console.log<\/code><\/pre>\n<p>Let\u2019s break this code down into pieces and show how intuitive it could be.\n<\/p>\n<p>\nThe first pipeline step could be called <strong>subject<\/strong>. The pipeline operator takes the subject and inserts it as a parameter to the next step, and the result of it becomes the <strong>subject<\/strong> of the next pipeline step, like in the following example:<\/p>\n<pre><code>document.getElementById('user-input').value\n\n\/\/ ^ this is the subject of the next step...\n|&gt; sanitize\n\n\/* ^ ... that will be added as a parameter of this step which desugars to\nsanitize(document.getElementById('user-input').value) which will be the\n\nsubject of the next step ...\n\n*\/\n|&gt; textualizeNumbers\n\n\/* ^ ... that will be added as a parameter of this step which desugars to\ntextualizeNumbers(sanitize(document.getElementById('user-input').value))\n\nwhich will be the subject of the next step ...\n\n*\/\n|&gt; console.log\n\n\/* ^ ... that will be added as a parameter of this step which\n\nfinally desugars to\n\nconsole.log(\ntextualizeNumbers(\n\nsanitize(\n\ndocument.getElementById('user-input').value\n\n)\n\n)\n\n);\n\n*\/<\/code><\/pre>\n<p><strong>Pipeline with more than one parameter<\/strong><\/p>\n<p>Let&#8217;s imagine that the <code>textualizeNumbers<\/code> function has a second parameter, which is a whitelist of numbers that shouldn&#8217;t be textualised, and we need to textualise only 0s and 1s. How should we add this to the pipeline chain?<\/p>\n<pre><code>document.getElementById('user-input').value\n|&gt; sanitize\n|&gt; (text =&gt; textualizeNumbers(text, ['0', '1']))\n|&gt; console.log<\/code><\/pre>\n<p>You could wrap your function that receives more than one parameter with an arrow function. Note that in the minimal proposal, arrow functions have to be wrapped with parenthesis; otherwise, you receive a syntax error. This parenthesis seems to be a syntax overhead, and we will cover how to work around this later.<\/p>\n<p><strong>Pipeline an async function<\/strong><\/p>\n<p>It\u2019s time to make our base example a little more complicated. Let\u2019s assume that our sanitize function treats the input on the server asynchronously and returns a promise. How do we deal with that?<\/p>\n<pre><code>document.getElementById('user-input').value\n|&gt; await sanitize\n\n\/\/ ^ this is ambiguous\n\n\/\/ await sanitize(x) or (await sanitize())(x)?\n|&gt; (text =&gt; textualizeNumbers(text, ['0', '1']))\n|&gt; console.log<\/code><\/pre>\n<p>We could use an <code>await<\/code> keyword to wait for the result and pass it forward, but there\u2019s a problem with this code. It\u2019s ambiguous, which makes it unclear how this code could be desugared and whether to use await <code>sanitize(x)<\/code> or <code>(await sanitize())(x)<\/code>.\n<\/p>\n<p>\nThere are still some issues with the syntax and the semantics in the minimal proposal. For now there are two competing proposals, which try to address this: the <strong>Smart Pipeline Proposal<\/strong> and the <strong>F# Pipeline Proposal<\/strong>.<\/p>\n<h4>The Smart Pipeline Proposal<\/h4>\n<p>In the smart pipeline proposal, the previous example could be written like this:<\/p>\n<pre><code>document.getElementById('user-input').value\n|&gt; await sanitize(#)\n\n\/\/ ^ whenever () or [] is needed we use Topic style\n|&gt; textualizeNumbers(#, ['0', '1']))\n\n\/* \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0^ This is the placeholder for the\n\n* \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0subject of the previous pipeline step\n\n*\/\n|&gt; console.log\n\n\/\/ ^ Bare style<\/code><\/pre>\n<p>The smart pipeline proposal defines two styles and a placeholder token for a specific pipeline step: The Bare style and Topic style and <em>#<\/em>. Whenever the usage of parenthesis or square brackets is needed, the Topic style is required. Otherwise, the Bare style is used. The <em># <\/em>placeholder means that the subject of the previous step should be placed in its place. The <em>#<\/em> placeholder is not final in the proposal, and this token could still be changed.\n<\/p>\n<p>\nIf you have a <code>curried<\/code> function, you have to use the Topic style; otherwise, you will get a syntax error, like in the example below:<\/p>\n<pre><code>x |&gt; myCurried(10) \/\/ Syntax Error\nx |&gt; myCurried(10)(#) \/\/ Fine<\/code><\/pre>\n<p>This proposal has extensive documentation for further enhancements; <a href=\"https:\/\/github.com\/js-choi\/proposal-smart-pipelines\/blob\/master\/readme.md\">you should check it out<\/a>.<\/p>\n<h4>The F# syntax proposal<\/h4>\n<p>The F# pipeline proposal tries to address the same issues with less syntax overhead. It creates an <code>await<\/code> step, which helps to address the ambiguity we spotted in the minimal proposal.<\/p>\n<pre><code>document.getElementById('user-input').value\n|&gt; sanitize\n|&gt; await\n\n\/\/ ^ await step\n|&gt; (text =&gt; textualizeNumbers(text, ['0', '1']))\n|&gt; console.log<\/code><\/pre>\n<p>The <code>await<\/code> step means that the previous step should be awaited to pass the subject to the next step. It desugars to the following code:<\/p>\n<pre><code>console.log(\ntextualizeNumbers(\nawait (\nsanitize(document.getElementById('user-input').value\n)\n)\n);<\/code><\/pre>\n<p>Note that it doesn\u2019t address the <em>\u201csyntax overhead\u201d<\/em> of wrapping an arrow function with parenthesis, but we will discuss a workaround later.\n<\/p>\n<p>\n<a href=\"https:\/\/github.com\/tc39\/proposal-pipeline-operator\">This proposal is in stage 1<\/a>, and the champion is Daniel Ehrenberg.<\/p>\n<h3>The Partial Application<\/h3>\n<p>When we were discussing the Pipeline operator, we saw an example of a pipeline step with some bound values and a wildcard, for which we use the computed value from the previous pipeline step.<\/p>\n<pre><code>...\ntextualizeNumbers(#, ['0', '1']))\n\n\/\/ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0^ wildcard\n...<\/code><\/pre>\n<p>This code could be considered a partial application, but what exactly does that mean?\n<\/p>\n<p>\nThe partial application refers to a process of giving a function with an N arity, returning another function with smaller arity by binding some of its parameters to a fixed value. Arity is the number of parameters that a specific function takes.\n<\/p>\n<p>\nTo present the concepts of the partial application, we can use the following code snippet.<\/p>\n<pre><code>const sayHi = (greetings, name, location) =&gt;\nconsole.log(`${greetings}, ${name}, from ${location}!`);\n\nsayHi('Yo', 'James', 'Colombia');\n\/\/ 'Yo, James from Colombia!<\/code><\/pre>\n<p>This snippet features a simple function, which receives three parameters to <code>console.log<\/code> a greetings phrase. So, let\u2019s say we have only the two first values, and the third one needs to be taken inside a resolved promise. How can we do this?<\/p>\n<pre><code>const greetings = 'Hello';\nconst name = 'Maria';\n\n\/\/ fetches the location from the server \u00af\\_(\u30c4)_\/\u00af\ngetLocation()\n.then(\nlocation =&gt; sayHi(greetings, name, location)\n);<\/code><\/pre>\n<p>This approach could be considered suboptimal, since we are creating two variables just for holding the value of the first two parameters. Maybe there\u2019s a better way.\n<\/p>\n<p>\nECMAScript has a way to do the partial application by using <code>Function.prototype.bind<\/code>. Often, we forget that the <code>.bind()<\/code> method can bind not only the context but parameters as well. With that new trick in mind, let\u2019s improve the previous example.<\/p>\n<pre><code>const sayHiByLocation = sayHi.bind(null, 'Hello', 'Maria');\n\ngetLocation()\n.then(\nlocation =&gt; sayHiByLocation(location)\n);<\/code><\/pre>\n<p>Since we don\u2019t need to bind a context, we are passing <code>null<\/code> as the first parameter and the <code>.bind()<\/code> method returns a new function with <code>'Hello'<\/code> and <code>'Maria'<\/code> bound to the first and second parameter. That looks a little better, doesn\u2019t it?\n<\/p>\n<p>\nHowever, what if we only have the <code>greetings<\/code> and <code>location<\/code> parameter? How can we bind the first and last parameter? The <code>Function.prototype.bind()<\/code> method can\u2019t do it, since it only binds the parameters in sequence (a, b and c). It can\u2019t bind a and c together and skip b.\n<\/p>\n<p>\nLet\u2019s try using curry instead. Although we can achieve the same result as a partial application with curry, curry is not equal to the partial application.\n<\/p>\n<p>\nCurry is a function that, given a function with arity N, returns a function with arity N-1. With this definition, we can write a solution like in the following code snippet:<\/p>\n<pre><code>const curriedSayHi = greetings =&gt;\nlocation =&gt;\nname =&gt; sayHi(greetings, name, location);\n\nconst sayHiTo = curriedSayHi('Hello')( 'Portugal');\n\ngetName()\n.then(name =&gt; sayHiTo(name));<\/code><\/pre>\n<p>Yes, it works, but we need to write a different curry function whenever we need another parameter order. Moreover, it may be hard to predict whether the next call will bind the next parameter or call the target function. Is there another way to do it without all of this boilerplate code?\n<\/p>\n<p>\nAlternatively, we can use the arrow function for the same purpose.<\/p>\n<pre><code>const sayHiTo = name =&gt; sayHi('Hello', name, 'Portugal');\n\ngetName()\n.then(name =&gt; sayHiTo(name));<\/code><\/pre>\n<p>As you can see, there are many ways to achieve a partial application in ECMAScript but none of them has been standardised. These use cases are the baseline problem that the partial application proposal tries to address.<\/p>\n<h4>The Partial application proposal<\/h4>\n<p>The Partial application proposal creates two new tokens to be placed inside a function call, which allow us to partially apply arguments to a specific function. The <code>?<\/code> (question mark) token for binding a single parameter and the <code>...<\/code> (ellipsis) token for multiple parameters. Following these definitions, we can revisit our previous example and rewrite it using the partial application proposal.<\/p>\n<pre><code>const sayHiTo = curriedSayHi('Hello', ?, 'Portugal');\n\ngetName()\n.then(name =&gt; sayHiTo(name));<\/code><\/pre>\n<p>,p>As you can see here, it becomes clear how to bind an arbitrary parameter, without adding code to handle that. Also, just by reading the code, it\u2019s trivial to figure out how much parameter is bound and which one should be provided.<\/p>\n<p><strong>The ellipsis token<\/strong><\/p>\n<p>In this proposal, there is another token mentioned, the ellipsis token (<code>...<\/code>). It works by spreading the parameters into a specific position. Does it sound complicated? Let\u2019s see it in action in the code.\n<\/p>\n<p>\nLet&#8217;s suppose we need to take the biggest number of a series, but if all numbers are smaller than zero, we return zero.<\/p>\n<pre><code>const maxGreaterThanZero = (...numbers) =&gt;\nMath.max(0, Math.max(...numbers));\n\nmaxGreaterThanZero(1, 3, 5, 7); \/\/ 7\nmaxGreaterThanZero(-1, -3); \/\/ 0<\/code><\/pre>\n<p>The code above is one possible solution to this problem. To achieve the goal, we nested two <code>Math.max<\/code> methods, where the inner one returns the biggest number given the numbers parameter. If the inner method returns a number smaller than zero, the outer method makes sure that zero is returned. Using the ellipsis token, we can achieve the same result with the following code.<\/p>\n<pre><code>const maxGreaterThanZero = Math.max(0, ...);\n\nmaxGreaterThanZero(1, 3, 5, 7); \/\/ 7\nmaxGreaterThanZero(-1, -3); \/\/ 0<\/code><\/pre>\n<p>Super simple, isn\u2019t it? Let&#8217;s check how this feature may work together with the pipeline operator.\n<\/p>\n<p>\nDo you remember when we spoke about the F# style with <code>await<\/code>? We pointed out that the syntax overhead of the arrow function wasn\u2019t covered there. But, with the partial application, we can rewrite that code like this.<\/p>\n<pre><code>document.getElementById('user-input')\n|&gt; sanitize\n|&gt; await\n|&gt; textualizeNumbers(?, ['0', '1'])\n\n\/* \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0^ this will return a function which expects\n\n* \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0? token to be the subject from the previous step\n\n*\/\n|&gt; console.log<\/code><\/pre>\n<p>The <a href=\"https:\/\/github.com\/tc39\/proposal-partial-application\">Partial application is in stage 1<\/a>, and the champion is Ron Buckton.<\/p>\n<h3>Conclusion<\/h3>\n<p>As you can see, many aspects of these proposals are still unsettled. The adoption of one may reshape the syntax or semantics of another feature proposal or even delete it.\n<\/p>\n<p>\nSo, should you use them in production? Not yet. However, I encourage you to try them out, check if they solve valid problems, add a star to the proposal repository you would like to support, and add comments for things that are unclear or even open an issue. Only with your feedback the committee can understand the developer\u2019s pain and make ECMAScript the language we love.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Explore three new JavaScript features that are currently at the proposal stage. There are examples of each function&#8217;s usage and details of how to provide feedback on the new features.<\/p>\n","protected":false},"author":2,"featured_media":19270,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12,24],"tags":[],"class_list":{"0":"post-19240","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-guest-posts","8":"category-web-design"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>3 features that could change the future of JavaScript - Heart Internet<\/title>\n<meta name=\"description\" content=\"We explore three new features that could change the future of Javascript, complete with usage examples and details of how to provide feedback.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"3 features that could change the future of JavaScript - Heart Internet\" \/>\n<meta property=\"og:description\" content=\"We explore three new features that could change the future of Javascript, complete with usage examples and details of how to provide feedback.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/\" \/>\n<meta property=\"og:site_name\" content=\"Heart Internet\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/heartinternet\/\" \/>\n<meta property=\"article:published_time\" content=\"2018-08-29T11:30:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/08\/people-looking-at-code-on-laptop-min.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1500\" \/>\n\t<meta property=\"og:image:height\" content=\"1000\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Eliot Chambers-Ostler\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@heartinternet\" \/>\n<meta name=\"twitter:site\" content=\"@heartinternet\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Eliot Chambers-Ostler\" \/>\n\t<meta name=\"twitter:label2\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"16 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/\"},\"author\":{\"name\":\"Eliot Chambers-Ostler\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28\"},\"headline\":\"3 features that could change the future of JavaScript\",\"datePublished\":\"2018-08-29T11:30:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/\"},\"wordCount\":2395,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/08\/people-looking-at-code-on-laptop-min.jpg\",\"articleSection\":[\"Guest Posts\",\"Web Design\"],\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/\",\"name\":\"3 features that could change the future of JavaScript - Heart Internet\",\"isPartOf\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/08\/people-looking-at-code-on-laptop-min.jpg\",\"datePublished\":\"2018-08-29T11:30:58+00:00\",\"description\":\"We explore three new features that could change the future of Javascript, complete with usage examples and details of how to provide feedback.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#primaryimage\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/08\/people-looking-at-code-on-laptop-min.jpg\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/08\/people-looking-at-code-on-laptop-min.jpg\",\"width\":1500,\"height\":1000},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.heartinternet.uk\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"3 features that could change the future of JavaScript\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/heartblog.victory.digital\/#website\",\"url\":\"https:\/\/heartblog.victory.digital\/\",\"name\":\"Heart Internet\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/heartblog.victory.digital\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/heartblog.victory.digital\/#organization\",\"name\":\"Heart Internet\",\"url\":\"https:\/\/heartblog.victory.digital\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp\",\"width\":992,\"height\":252,\"caption\":\"Heart Internet\"},\"image\":{\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/heartinternet\/\",\"https:\/\/x.com\/heartinternet\",\"https:\/\/www.linkedin.com\/company\/heart-internet-ltd\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28\",\"name\":\"Eliot Chambers-Ostler\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\/\/heartblog.victory.digital\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg\",\"contentUrl\":\"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg\",\"caption\":\"Eliot Chambers-Ostler\"},\"url\":\"https:\/\/www.heartinternet.uk\/blog\/author\/eliot-chambers-ostler\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"3 features that could change the future of JavaScript - Heart Internet","description":"We explore three new features that could change the future of Javascript, complete with usage examples and details of how to provide feedback.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/","og_locale":"en_GB","og_type":"article","og_title":"3 features that could change the future of JavaScript - Heart Internet","og_description":"We explore three new features that could change the future of Javascript, complete with usage examples and details of how to provide feedback.","og_url":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/","og_site_name":"Heart Internet","article_publisher":"https:\/\/www.facebook.com\/heartinternet\/","article_published_time":"2018-08-29T11:30:58+00:00","og_image":[{"width":1500,"height":1000,"url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/08\/people-looking-at-code-on-laptop-min.jpg","type":"image\/jpeg"}],"author":"Eliot Chambers-Ostler","twitter_card":"summary_large_image","twitter_creator":"@heartinternet","twitter_site":"@heartinternet","twitter_misc":{"Written by":"Eliot Chambers-Ostler","Estimated reading time":"16 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#article","isPartOf":{"@id":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/"},"author":{"name":"Eliot Chambers-Ostler","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28"},"headline":"3 features that could change the future of JavaScript","datePublished":"2018-08-29T11:30:58+00:00","mainEntityOfPage":{"@id":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/"},"wordCount":2395,"commentCount":0,"publisher":{"@id":"https:\/\/heartblog.victory.digital\/#organization"},"image":{"@id":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#primaryimage"},"thumbnailUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/08\/people-looking-at-code-on-laptop-min.jpg","articleSection":["Guest Posts","Web Design"],"inLanguage":"en-GB","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/","url":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/","name":"3 features that could change the future of JavaScript - Heart Internet","isPartOf":{"@id":"https:\/\/heartblog.victory.digital\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#primaryimage"},"image":{"@id":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#primaryimage"},"thumbnailUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/08\/people-looking-at-code-on-laptop-min.jpg","datePublished":"2018-08-29T11:30:58+00:00","description":"We explore three new features that could change the future of Javascript, complete with usage examples and details of how to provide feedback.","breadcrumb":{"@id":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/"]}]},{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#primaryimage","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/08\/people-looking-at-code-on-laptop-min.jpg","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2018\/08\/people-looking-at-code-on-laptop-min.jpg","width":1500,"height":1000},{"@type":"BreadcrumbList","@id":"https:\/\/www.heartinternet.uk\/blog\/3-features-that-could-change-the-future-of-javascript\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.heartinternet.uk\/blog\/"},{"@type":"ListItem","position":2,"name":"3 features that could change the future of JavaScript"}]},{"@type":"WebSite","@id":"https:\/\/heartblog.victory.digital\/#website","url":"https:\/\/heartblog.victory.digital\/","name":"Heart Internet","description":"","publisher":{"@id":"https:\/\/heartblog.victory.digital\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/heartblog.victory.digital\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":"Organization","@id":"https:\/\/heartblog.victory.digital\/#organization","name":"Heart Internet","url":"https:\/\/heartblog.victory.digital\/","logo":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/02\/HeartInternet_Logo_Colour.webp","width":992,"height":252,"caption":"Heart Internet"},"image":{"@id":"https:\/\/heartblog.victory.digital\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/heartinternet\/","https:\/\/x.com\/heartinternet","https:\/\/www.linkedin.com\/company\/heart-internet-ltd"]},{"@type":"Person","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/58ed7f27cc0f3ab6e69135742a5eee28","name":"Eliot Chambers-Ostler","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/heartblog.victory.digital\/#\/schema\/person\/image\/","url":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg","contentUrl":"https:\/\/www.heartinternet.uk\/blog\/wp-content\/uploads\/2025\/08\/cropped-Eliot-96x96.jpg","caption":"Eliot Chambers-Ostler"},"url":"https:\/\/www.heartinternet.uk\/blog\/author\/eliot-chambers-ostler\/"}]}},"_links":{"self":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts\/19240","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/comments?post=19240"}],"version-history":[{"count":0,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/posts\/19240\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/media\/19270"}],"wp:attachment":[{"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/media?parent=19240"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/categories?post=19240"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.heartinternet.uk\/blog\/wp-json\/wp\/v2\/tags?post=19240"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}