最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

function - Javascript: When and when not to use "this" - Stack Overflow

programmeradmin0浏览0评论

Im curious when it is needed/best practice to use the keyword this. I understand that this is used when determining a functions this value but is it always needed?

The reason I am asking is because I have a internal function and it is called within my module and all it really does is sort some data you pass it. My question is should I call this function using the this keyword or stand alone.

E.g:

function formatSomeData(data){
  //code........
}

this.formatSomeData(data);

        OR

formatSomeData(data);

I get that the context of where the function is being called and what its purpose is matters in answering the question, but in this case like I mentioned, I really don't need to access the this object at any point. Is it still good practice to use it when calling functions? What I'm asking is not so much as to how "this" works, but when is it appropriate to use it and when isn't it.

Im curious when it is needed/best practice to use the keyword this. I understand that this is used when determining a functions this value but is it always needed?

The reason I am asking is because I have a internal function and it is called within my module and all it really does is sort some data you pass it. My question is should I call this function using the this keyword or stand alone.

E.g:

function formatSomeData(data){
  //code........
}

this.formatSomeData(data);

        OR

formatSomeData(data);

I get that the context of where the function is being called and what its purpose is matters in answering the question, but in this case like I mentioned, I really don't need to access the this object at any point. Is it still good practice to use it when calling functions? What I'm asking is not so much as to how "this" works, but when is it appropriate to use it and when isn't it.

Share Improve this question edited Feb 14, 2018 at 21:39 Phil Dimeski asked Feb 14, 2018 at 6:26 Phil DimeskiPhil Dimeski 511 silver badge7 bronze badges 8
  • If its a method of some kind, that means that the function is somehow directly related to an object, then its a good design decision to use this. Otherwise not – Jonas Wilms Commented Feb 14, 2018 at 6:30
  • 3 Possible duplicate of How does the "this" keyword work? – Vasyl Moskalov Commented Feb 14, 2018 at 6:30
  • By the way this.formatSomeData(data); wont work in your case so the answer is obvious – Jonas Wilms Commented Feb 14, 2018 at 6:31
  • @JonasW. it might. In non-strict mode, this will point to window and any declaration not in a function will be a part of global scope. – Rajesh Commented Feb 14, 2018 at 6:33
  • @rajesh "in non-strict mode" ... talking about bad practices here... – Jonas Wilms Commented Feb 14, 2018 at 6:40
 |  Show 3 more ments

6 Answers 6

Reset to default 5

when it is needed/best practice to use the keyword this

This is usually used when you want to access something in some. So for instance, if you have a custom object and want to use some property inside some method, you should use this.

function Person(fname, lname){
  this.fname = fname;
  this.lname = lname;
  this.fullName = function(){
    return this.fname + ' ' + this.lname;
  }
}

var p = new Person('foo', 'bar');
console.log(p.fullName())

If you see, in current constructor, I created a function(fullName) which needs to access fname and lname properties of the object it is part of. This is a place this must be used.


Now while declaration, when to use this?

Any property in a constructor that is a part of this will be a part of the object. So if you need something that is only accessible to you but not outside, you can use function instead of this.

function Person(fname, lname){
  var self = this;
  self.fname = fname;
  self.lname = lname;
  
  // This function is private
  function getFullName() {
    var name = '';
    var seperator = '';
    if (fname) {
      name += self.fname;
      seperator = ' ';
    }
    if (lname) {
      name += seperator + self.lname;
    }
    return name;
  }
  this.fullName = function(){
    return getFullName();
  }
}

var p = new Person('foo', 'bar');
console.log(p.fullName())


As for your code, I have already explained in ment why it works:

In non-strict mode, this will point to window and any declaration not in a function will be a part of global scope.

But as rightly pointer by @Jonas W its a bad practice. Why it is bad?

  • Any variable defined without declaration statement(var|let|const) will bee part of global scope.
  • Any variable with declaration statement outside any functions will bee part of global scope.

For a starting JS developer it might be easiest to get concept of This by using it in an event listener callback. I. e., "click" event binds This to object which is the target (Like "look, i clicked on THIS!").

<ul class="dynamic-list" id="myList">
  <li class="dynamic-list__item">Item 1</li>
  <li class="dynamic-list__item">Item 2</li>
  <li class="dynamic-list__item">Item 3</li>
</ul>

<script type="text/javascript">
  let listItems = document.getElementById("myList").childNodes;
  [...listItems].forEach(function(item) {
    item.addEventListener("click", removeListItem, false);
  })

  // Callback for event, using THIS
  function removeListItem() {
    // Log the text content of <li> to the console. Which one? THIS one.
    console.log(this.textContent);

    // Get the parent of what? Of THIS! And remove its child. Which one? THIS one!          
    this.parentNode.removeChild(this);
  }

</script>

Of course Rajeshs answer is much, much more plex, but I hope THIS can be also helpful…

Programming is a way to express things so that puters and humans can understand them.

Is it still good practice to use it when calling functions?

There is no exact answer. Both of your snippets do work. So the puter is able to understand it. However the second one is maybe confusing for humans (aka your coworkers):

 this.someFunc();

What should this refer to? Yes technically it refers to window, but from a human point of view it is unclear. Thats why i would definetly not refer to this in this case. However there are other good usecases for it:

 function changeColor(){
   //When just looking here it makes no sense to refer to this
   this.color = "green";
}

const car = { color: "grey" };

 //But now it makes sense as `this` refers to the `car` it is called on
car.changeColor = changeColor;

TLDR: Use this to refer to methods/properties, and leave it away when refering to pure functions and variables.

Let me help you with this piece of code!

let emp_detail={
 fname:"jemish",
 lname:"italiya",
 detailStatement:function() {
  return this.fname+" "+this.lname;
  }
}

Let me give you another example

function Data(){
return this.result
}
var a=Data.bind({result:"I am the result!"})();
console.log(a)    //I am the result!

'This' is used inside a function and it contains the value of the object that invokes the function.

For example:

function a(){
 this.newVariable = 'Phil';
}
a();
console.log(newVariable); //This line would display Phil

In this case, even though we just define newVariable inside the function a(). The object that invokes the function is the global object window, so 'this' points to window and this.newVariable is at the global scope.

Another example would be:

var c={
  log:function(){
    this.name = 'Phil';
   }    
}

In this case, 'this' points to the object c, since the log function will be invoked by c.

We have more tricky cases in the use of the object 'this' in Javascript. This is a good article to grasp the concept: http://javascriptissexy./understand-javascripts-this-with-clarity-and-master-it/

One could see this as an argument that has a default value. Consider the apply and call functions.

function theThis () {
  return this
}

theThis.call('hello') // => "hello"
theThis.apply('world') // => "world"

This example is not an explanation of the behavior of this, but more a demonstration of the use of this as an argument that isn't part of the arguments array. You could say it is an argument that has its own special keyword.

The exact value that this bees; depends on a (long) list of rules. The this keyword can therefore be confusing and often unnecessarily so. In most cases, it is better to write your code in a way that makes the use of this redundant. Let's look at a fullName example.

function fullName({firstName, lastName}) {
  return `${firstName} ${lastName}`
}

const person = {
  firstName: 'John',
  lastName: 'Doe',
}

fullName(person) // => "John Doe"

We implemented the plete fullName feature without this, which is great because we don't have to worry about the rules of this. Therefore, we don't need to use call, bind, and apply to force the function to be called with the correct this. Not to mention, the () => {} syntax for defining functions which adds to the list of how the value of this is determined.

Some people might want an object that also contains methods that can be instantiated, the prototypal inheritance approach. This mon approach is not OK as it will cause confusion in many cases. Assigning a function on the object to another object is one of those examples. Just because you know this little trick, does not mean a developer with a different programming background knows about this (confusing) behavior.

> a = {id: 0, thiz() { return this; } }
{ id: 0, thiz: [Function: thiz] }
> b = {id: 1}
{ id: 1 }
> b.thiz = a.thiz
[Function: thiz]
> b.thiz()
{ id: 1, thiz: [Function: thiz] }

By doing this you have also conflated puted properties and behaviours with the state.

I remember running into these bugs where I would assign a method to the view model of some SPA ponent. Poor me back in the early days of Angular.

I often read that the use of this enables code re-use and concise implementations. I find this statement to be untrue and misleading. Let's pare implementations of the fullName example.

With this

class Person {
  constructor(details)  {
    Object.assign(this, details)
  },
  fullName() {
    return `${this.firstName} ${this.lastName}`
  }
}

export default Person

//

import Person from './person.mjs'

new Person({
  firstName: 'John',
  lastName: 'Doe',
}).fullName()

Without this

export function fullName({firstName, lastName}) {
  return `${firstName} ${lastName}`
}

//

import { fullName } from './person.mjs'

fullName({
  firstName: 'John',
  lastName: 'Doe',
})

The implementation without this

  • has fewer objects
  • is written with less code
  • requires less knowledge of the language
  • is just as expressive.

However, there are use-cases for using this that are very specific.

Keeping backwards patibility while passing more state to a function.

Previously, I showed that you can write functions without this. But what if code ends up being used, and you want to re-use that code while extending functionality? Here you need an "escape-hatch." The this can be exactly that. You are most likely still better off doing a major version bump and updating the consuming code to adopt those changes. If, however, you need or want to keep the API, the this can be your way out to pass some extra state.

The library I'm using already uses this.

Don't be too strict about not using this and adopt the API of the library you end up picking. The designer of that library should assume their API is being used the way they prescribe it. If you don't like it, consider using a different library or write your own.

Conclusion: Using this incorrectly can lead to confusion in JavaScript code. It is remended to bee familiar with module and lexical scoping to write more readable code. Avoiding the dynamic behavior of this can also help in this regard. Additionally, most features of JavaScript, such as prototypal inheritance, can be used without relying on the this keyword.

Links:

  • https://www.freecodecamp/news/removing-javascripts-this-keyword-makes-it-a-better-language-here-s-why-db28060cc086/
发布评论

评论列表(0)

  1. 暂无评论