-1

i made a button called btn and i gave it a text

btn = document.createElement('button')
btn.textContent = "Hello World"

i want to make it alert its textContent when it gets clicked.

i know i can use:

btn.onclick = function(){alert(this.textContent)}

but lately i have learnt about these arrow functions and i wanted to use it here so i made this

btn.onclick = ()=>{alert(this.textContent)}

and

btn.onclick = ()=> alert(this.textContent)

but both of them alert undefined

so how can i make it ?

badr
  • 47
  • 6
  • 1
    Here's the most important thing: Arrow functions _do not have their own `this`_, they inherit the `this` from whatever context they were created in - like a variable only available in your function scope. In global context, this means `this` refers to the window, not the element. Read the docs for more info and detail: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions – somethinghere Dec 28 '20 at 02:32
  • _“lately I have learnt about \[these\] arrow functions”_ — Where have you learned about being able to use `this` in an arrow function like that? Please read the [documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions) before using features you don’t really know how to use, and before asking. – Sebastian Simon Dec 28 '20 at 02:44
  • sorry i meant i have heard about it – badr Dec 28 '20 at 02:46

2 Answers2

1

this indicates its parent scope in arrow function, while it indicates button component in regular function. So in arrow function, you need to use btn.textContent instead of this.textContent

btn = document.createElement('button')
btn.textContent = "Hello World"
// btn.onclick = function(){alert(this.textContent)}
btn.onclick = (event) => {alert(event.target.textContent)}
document.body.appendChild(btn);

btn = document.createElement('button')
btn.textContent = "Hello World"
btn.onclick = function(){alert(this.textContent)}
// btn.onclick = (event) => {alert(event.target.textContent)}
document.body.appendChild(btn);
Prime
  • 2,809
  • 1
  • 7
  • 23
1

Arrow functions are not bound to a this object, as they act more like locally defined clumps of code you can run. This is why using this does not work - you created the arrow functions in the global context, where this was defined to refer to the Window. The way to solve this is to use another useful little detail: the Event argument:

let i = 0;

document.body.onclick = event => event.target.textContent = i++;
html,body { height: 100%; }
div { position: fixed; top: 0; left: 0; width: 100%; height: 100%; }
<div>0</div>

The event object can be used in this case, and it's better to use this record than to rely on a this here. this is mostly useful when you start creating prototypes and classes and need to refer to something internal. When they get bound to methods, it's a bit of a hodge-podgey mess to be certain which object it is referring to, and it's a bit complex, so better to use already provided values that you know will always be correct.

somethinghere
  • 16,311
  • 2
  • 28
  • 42