By Michael Thiessen translated by Techalyst

Like it and see. Make it a habit

In this paper,GitHub Github.com/qq449245884…Has included more categories of previous articles, as well as a lot of my documentation and tutorial material. Welcome Star and Perfect, you can refer to the examination points for review in the interview, I hope we can have something together.


When we were using Vue on a happy development project, we suddenly reported an error:

this is undefined
Copy the code

Don’t worry, you’re not the only one. I’ve had this problem many times, so let’s see how to solve it.

One possible reason is confusion between regular functions and arrow functions. If you run into this problem, I’m guessing you use arrow functions. If you replace the arrow function with a regular one, it might fix this for you.

Let’s dig a little deeper and try to understand why that is.

After all, knowledge is power, and if we know the cause of the problem, we can avoid a lot of frustration and wasted time in the future.

There are other reasons why such errors might occur.

  • usefetchaxiosTo get the data
  • Use aslodashunderscoreThis class library

Understand the two main types of functions

In JS, we have two different kinds of functions. They work in almost the same way, except they handle variables differently.

This creates a lot of confusion for new and old Javascript developers, but it’s good to have this confusion when we figure it out.

The conventional function

Regular functions can be defined in several different ways.

The first method is less common in Vue components because it takes longer to write:

methods: {
  regularFunction: function() {
    // Do some stuff
  }
}
Copy the code

The second method is shorthand, which we often use:

methods: {
  shorthandFunction() {
    // Do some stuff
  }
}
Copy the code

In a regular function like this, this will refer to the “owner” of the function. Since we defined it on the Vue component, this refers to the Vue component.

In most cases, we should use regular functions in Vue, especially at creation time

  • methods
  • computed props
  • watched props

While regular functions are usually what we need, arrow functions are also handy.

Arrow function

Arrow functions can be shorter and faster to write, so they have recently gained wide popularity. However, they are not very different in defining methods on objects, as we did when we wrote the Vue component.

Here’s what they look like on the Vue component:

methods: {
  arrowFunction: () => {
    // Do some stuff
  }
}
Copy the code

Real differences come into play when dealing with this problem.

The arrow function is lexical, meaning that the arrow function gets this from its context.

If you try to access this from inside the arrow function on the Vue component, you will get an error because this does not exist

data() {
  return {
    text: 'This is a message',
  };
},
methods: {
  arrowFunction: () => {
    console.log(this.text);  // ERROR! this is undefined
  }
}
Copy the code

In short, try to avoid using arrow functions on Vue components. This will save a lot of headaches and confusion.

It’s nice to use the arrow function sometimes, but this only works if you don’t reference this.

computed: {
  location: () => window.location,
}
Copy the code

Now that we know the two main function types, how do we use them correctly?

Anonymous functions

Anonymous functions are useful when we just need to create a function and don’t need to call it from anywhere else.

Here are some scenarios where anonymous functions are used

  • useaxiosfetchTo fetch data
  • filter,mapandreduceEqual function method
  • Anywhere in the Vue method

Here’s an example:

// Fetching data
fetch('/getSomeData').then((data) => {
  this.data = data;
});

// Functional methods
const array = [1, 2, 3, 4, 5];
const filtered = array.filter(number => number > 3);
const mapped = array.map(number => number * 2);
const reduced = array.reduce((prev, next) => prev + next);
Copy the code

As you can see from the example, in most cases we use the arrow function when creating anonymous functions. We usually use arrow functions for several reasons

  • Shorter, more concise syntax
  • Improved readability
  • This comes from the parent class

Arrow functions can also be used as anonymous functions in the Vue method.

Wait, didn’t we just find out that the arrow function doesn’t work when we try to access this?

That’s the difference.

When we use the arrow function in the normal function or the shorthand function, the normal function sets this to our Vue component, but the arrow function is different.

Here’s an example:

data() { return { match: 'This is a message', }; }, computed: { filteredMessages(messages) { console.log(this); // Vue const filteredMessages = messages.filter(// reference our Vue component (message) => message.includes(this.match)); return filteredMessages; }}Copy the code

The filter method can access this.match because the arrow function uses the same context as the filteredMessages method. Because this method is a regular function (and not an arrow function), its own context is set to a Vue instance.

Let’s take a closer look at how to fetch data using AXIos or FETCH.

Use the correct function when retrieving data

If you’re using FETCH or AXIos to fetch asynchronous data, it’s best to use Promise. Promise likes the anonymous arrow functions, which also make dealing with this much easier.

If you’re getting some data and want to set it up on your component, this is the right way to do it:

export default { data() { return { dataFromServer: undefined, }; }, methods: { fetchData() { fetch('/dataEndpoint') .then(data => { this.dataFromServer = data; }) .catch(err => console.error(err)); }}};Copy the code

Notice how we can use regular functions as methods on the Vue component and then use anonymous arrow functions inside the Promise

.then(data => {
  this.dataFromServer = data;
})
Copy the code

In the fetchData() scope, we set this as a Vue component because it is a regular function. Since the arrow functions use an external scope as their own scope, the arrow functions also set this to our Vue component.

This allows us to access the Vue component through this and update The dataFromServer.

But what if you need to pass functions to a help library, such as Lodash or underscore

Used with Lodash or Underscore

Suppose we have a Vue component that wants to use Lodash or Underscore methods. How to prevent this is undefine error.

If you’ve ever used React, you’ve probably seen something similar.

This is what we did with Vue.

created() {
  this.methodToDebounce = _.debounce(this.methodToDebounce, 500);
},
methods: {
  methodToDebounce() {
    // Do some things here
  }
}
Copy the code

That’s it!

All we need to do is get the function, wrap it in debounce, and return a new function with debounce built in. Now, when we call this.methodTodebounce () on the Vue component, we will call the Debmentioning version.

What is lexical scope

As mentioned earlier, the main reason for the difference between regular and arrow functions has to do with lexical scope. Let’s analyze what that means.

First, a scope is any region in a program where variables exist. In Javascript, the window variable has global scope and is available anywhere. Although most variables are limited to the function that defines them, the class or module to which they belong.

Second, the word “lexical” simply means that the scope depends on how you write the code. Some programming languages determine what is in scope only when the program is running. This can be confusing, so most languages just use lexical scopes.

Arrow functions use lexical scope, while regular and shorthand functions do not.

The trickiest part here is how lexical scope affects this in functions. For arrow functions, this is bound to this in the outer scope. The this binding of regular functions is a bit strange, which is why the arrow function was introduced, and why most people use it as often as possible.

How does scope work in functions

Here are some examples that demonstrate how scopes work differently between these two function types

Value = 'Bound to the window'; Const object = {// Value: 'Bound to the object', arrowFunction: () => {console.log(this.value); // 'Bound to the window' }, regularFunction() { console.log(this.value); // 'Bound to the object' } };Copy the code

Bind a scope to a function

We can change the binding of this using the bind method

const boundFunction = unboundFunction.bind(this);
Copy the code

This gives us more flexibility in writing Vue components and makes it easier to reuse methods. Of course, the readability is relatively poor, and you should avoid using it too often.


The bugs that may exist after code deployment cannot be known in real time. In order to solve these bugs, I spent a lot of time on log debugging. Incidentally, I recommend a good BUG monitoring tool for youFundebug.

Original: www.techalyst.com/posts/vuejs…


communication

This article is updated every week, you can search wechat “big move the world” for the first time to read and urge more (one or two earlier than the blog hey), this article GitHub github.com/qq449245884… It has been included and sorted out a lot of my documents. Welcome Star and perfect. You can refer to the examination points for review in the interview.