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?
source to share
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 propertiesaccount.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 operatorreturn
that returns something else, as in your functionaccount2()
.
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.
source to share