Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Basic Arrow Syntax

Michal Janek
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Michal Janek
Front End Web Development Techdegree Graduate 30,654 Points

Still not sure about THIS in arrow syntax.

I have a code in HTML

<!DOCTYPE html>
<html>
    <head>
        <title>Javascript Essesntials - by Avelx</title>
        <meta charset="UTF-8"/>
    </head>
    <body>

        <span>Background color:</span>
        <select id="background">
          <option value="Red">Red</option>
          <option value="Green">Green</option>
          <option value="Blue">Blue</option>
        </select>

        <span>Width:</span>
        <select id="width">
          <option value="100px">100px</option>
          <option value="200px">200px</option>
          <option value="300px">300px</option>
        </select>

        <span>Height:</span>
        <select id="height">
          <option value="100px">100px</option>
          <option value="200px">200px</option>
          <option value="300px">300px</option>
        </select>

        <br/><br/>

        <div id="content" style="background:red; width:100px; height:100px;"></div>

        <script src="script.js"></script>

    </body>
</html>

It will show a div element and few dropdown select buttons. The idea is to change the div according to the dropdown options

Here is JS that will work:

const selectElements = document.querySelectorAll('select');
const divElement = document.querySelector('div');

function changeStyle () {

   let styleType = this.id;
   let val = this.value;

  divElement.style[styleType] = val;
}

for (let i = 0; i < selectElements.length; i++) {
  selectElements[i].addEventListener('change', changeStyle);
}

However let us look on the changeStyle() function. I want to change it into arrow syntax but then it does not work. I suspect the THIS is involved, but cannot figure out how it is linked.

const changeStyle =  ()=> {

   let styleType = this.id;
   let val = this.value;

  divElement.style[styleType] = val;
}

I have tried to read up more about it but was a bit overwhelmed by MDN. If anyone knows some summary It would be a great help. Thanks

2 Answers

Steven Parker
Steven Parker
229,920 Points

Arrow functions do not use "this" the same way as conventional functions.

So when you create an event handler with an arrow function, be sure to pass in the event object and use the target property instead of "this":

const changeStyle =  (e) => {
   let styleType = e.target.id;
   let val = e.target.value;

  divElement.style[styleType] = val;
}

For more info, see the MDN page on Arrow Functions.

When you call on a function in JS, there is an execution context stack created. Think of it as a "behind the scenes" object with certain properties on it. One of these properties would be the 'this' property, which is assigned when the function is first called, but before execution. The 'this' property inside of an event handler always refers to the element it was triggered on. So in your case it would be all of the select buttons and will always refer to them.

The reason why your code with the function declaration works is because the 'this' property is assigned to the select buttons and references them when you call on 'this' within the function, like you did with 'this.id' and 'this.value'. This happens with function declarations.

With lambda functions the 'this' property within its context stack IS NOT assigned to anything and doesn't refer to your select buttons anymore. The lambda function will look up its lexical scope in order to find the nearest 'this' value instead. In your case it would be the global object and come up as undefined when you called on 'this.id' and 'this.value'.

It's more or less something like that lol.

Steven Parker
Steven Parker
229,920 Points

:warning: These comments apply to arrow functions, not to lambda functions. In JavaScript, lambdas can be constructed using either conventional or arrow notation. The difference to "this" occurs only when the arrow notation is used.