Something I noticed today confused me.
When I first used Vue there were two mon ways to define a method.
methods: {
foo: () => {
//do something
}
}
and
methods: {
foo() {
//do something
}
}
Both worked without any problem.
Today I defined a method like the first example and I had problems with the scope of this
inside the function.
For context:
I have data defined like this:
data() {
return {
fooVar: ''
}
}
and my method was defined like this.
methods: {
foo: () => {
console.log('Foo: '+this.fooVar);
}
}
When I checked the console it said
Foo: undefined
I then change the method declaration to
foo() {
console.log('Foo: '+this.fooVar)
}
and it worked without any problem.
So since I thought that foo() {...}
and foo: () => {...}
are the same thing (apart from the declaration itself) I was wondering if the scope of the function changes between those two ways.
Does it change and if so why does it change?
Something I noticed today confused me.
When I first used Vue there were two mon ways to define a method.
methods: {
foo: () => {
//do something
}
}
and
methods: {
foo() {
//do something
}
}
Both worked without any problem.
Today I defined a method like the first example and I had problems with the scope of this
inside the function.
For context:
I have data defined like this:
data() {
return {
fooVar: ''
}
}
and my method was defined like this.
methods: {
foo: () => {
console.log('Foo: '+this.fooVar);
}
}
When I checked the console it said
Foo: undefined
I then change the method declaration to
foo() {
console.log('Foo: '+this.fooVar)
}
and it worked without any problem.
So since I thought that foo() {...}
and foo: () => {...}
are the same thing (apart from the declaration itself) I was wondering if the scope of the function changes between those two ways.
Does it change and if so why does it change?
Share Improve this question asked Mar 11, 2019 at 12:48 LLJ97LLJ97 5003 gold badges6 silver badges19 bronze badges 1- 1 I came across the same problem and I found this article helpful. Kindly check Arrow function of es6 too.. – Víñịt Vịłłă Commented Mar 11, 2019 at 12:53
2 Answers
Reset to default 6This not so much a question about Vue as about javascript itself.
In short, arrow functions(defined with (x) => { doSomething(x); } are not the same as usual functions. They have no "this" of their own and have access only to the scope they are defined in (if there is no scope, this defaults to window or global(in nodejs)). They should preferably be used in places where they don't function as methods for an object instance.
You stumbled upon the significant difference between 'classic' function declaration and fat arrow
declaration.
The main difference is related to how this
is treated.
When using function
to declare a function you'll get a new this
object (Note that sometimes the new this
object is actually undefined
). When using fat arrow
declaration you'll end up using the this
from the scope where the function is declared.
The main reason fat arrow was introduces is the fact that, in callbacks, when wanting to access the declaration scope this
you had to save that value using a different name and use it. For instance
function doSmth () {
var times = 0
var that = this //or var self = this
setInterval( function () {
that.times ++
console.log(that.time)
}, 1000)
}
This was cumbersome and fat arrow syntax was introduced. Also the new syntax is shorter and (arguably) easier to understand.
Another important difference between fat arrow
and function
declaration is that Function.apply doesn't work on fat arrow declaration. Because this
is bound to the declaring scope it is not changed by the call to apply
. This is important because there are libraries counting on the fact that they can change this
when calling a callback. They usually make this difference known in the docs, but it is important to be aware of the distinction.