Javascript this. Function versus return function?

I'm a little confused learning all the new ES6 and ES5 syntax with javascript and when it comes to functions / classes using methods and calling those methods, I can't tell what the "right way" is.

For example, take this code:

function account(amount) {
    let cash = amount;
  this.setCash = function(amt)
  {
    cash = amt;
  }
  this.getCash = function()
  {
    return cash;
  }
}
var person = new account(100);
console.log(person.getCash()); //returns 100
person.setCash(150);
console.log(person.getCash()); //returns 150

      

Works fine as expected (this is how I originally saw the methods used when going through the tutorials).

However, I've seen this sometimes:

function account2(amount) {
    let cash = amount;
    function setCash(amt)
  {
    cash = amt;
  }
  function getCash()
  {
    return cash;
  }
  return{
    getCash,
    setCash
  }
}
var person2 = new account2(50);
console.log(person2.getCash()); //returns 50
person2.setCash(175);
console.log(person2.getCash()); //returns 175

      

They both work great, and do what I think they should. However, is this one of the oldest ways to do it? or less correct, maybe? This is my biggest hurdle in learning JS right now, as there are so many different ways to do something in ES6 here as easy as making a "class" in JS using methods.

Personally, the first way seems easier, since you don't need to return functions ... but for example at work I see that the second way is mainly used?

+3


source to share


2 answers


If you removed new

from the second version (more on that in an instant), then both of your examples are great for creating an object with private data accessible via public get / set methods. Which one you choose is personal preference or depends on whether you want to extend the functionality even further with prototypes, etc.

The reason I propose to remove new

from the second version is that while both examples work, the first is "normal" use new

, but the second is "incorrect" use of the operator new

- not a syntax error, just semantically incorrect and potentially incorrect for other people reading your code.

So why is the second use new

semantically incorrect? When you say var person = new account(100)

:

  • A new object is created with a prototype account.prototype

    . This means that the new object inherits any methods and properties account.prototype

    , as well as its prototype, etc. (In your case, you didn't define any methods on the prototype, but you could.)
  • The function account()

    this

    will refer to the object created in step 1. That is why you can attach methods to it usingthis.setCash = ...

  • By default, a new object is returned from account()

    . This step will not occur if you have an explicit operator return

    that returns something else, as in your function account2()

    .

So the first example person instanceof account

is true

because the default object was returned. In the second example person2 instanceof account2

- false

because another object was returned - this is misleading to people reading your code, because when they see person2 = new account2()

, they can reasonably expect to person2

be an instance, account2

but they are not. It's also a bit inefficient because the JS engine has the problem of creating an object for you and then you don't use it.



Thus, the second example would be more "correct" without new

providing the same behavior minus the unnecessary creation of an automatic object:

var person2 = account2(50);

      

(Almost) any JS function you write can be called with new

, but there is a convention in which we describe functions to be called with new

as "constructors", and usually the function name is capitalized, therefore account()

, not account()

. (The writing does not change the behavior; it is just an additional hint for people reading the code.)

Note that using new

is not the only way to bind objects to specific prototypes: it's old school, but still great, but you can use Object.create()

.

By the way, the behavior in question is not new in ES5 or 6, although the let

syntax of the object shortcut literal account2

is new.

+4


source


When instantiated with, the new

keyword is this

returned implicitly, where, as when assigning the function to a variable without new

, you need to explicitly use return

.



+1


source







All Articles