0

I'm new to JavaScript and I'm struggling to understand how

function Person(age, name, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}

is any different than

function Person(age, name, gender) {
    name = this.name;
    age = this.age;
    gender = this.gender;
}

Because with the first version of the code, everything runs smoothly and when I create

var Bob = new Person(30, "Bob", "male");

and do this

document.getElementById("demo").innerHTML = Bob.name;

it successfully prints "Bob". But when I run the second version of the code I get undefined. Why or how does it matter which side of the equal sign something is on?

  • 1
    The first is correct, because Javascript requires a scope, _always_. The `this` variable is always relative to the block. In the first case, `this` in your instance of `Person`. – Mr. Polywhirl Sep 09 '20 at 15:44
  • 1
    It's always "assign the value on the right to the place on the left". If that wasn't the case then how should the runtime know if you want `a = b` to change a or b? What you're asking is basically "why are there grammar rules in English? Shouldn't we just be able to say words and make them mean what we want"? – Joachim Sauer Sep 09 '20 at 15:46
  • In your first example you are assigning `name` to `this.name`. In second you are assigning `this.name` to `name`, in this example `this.name` is undefined, therefore it's assigned to name. – kyle Sep 09 '20 at 15:47
  • @JoachimSauer Ah, I never thought of it that way haha. Thanks! – astralproject Sep 09 '20 at 15:51
  • If you don't understand this, you need to do more studying of the basics of programming. In almost all languages, the direction of an assignment is important. – Barmar Sep 09 '20 at 17:38
  • @JoachimSauer To be fair, there are languages where the order doesn't matter, such as Prolog. In that language, `=` specifies logical equivalence, and it will fill in whichever is unknkown. – Barmar Sep 09 '20 at 17:39
  • @Barmar: true, but those languages are a clear minority (and even those have a "grammar" that explains what each given statement does and don't just "do stuff" arbitrarily). – Joachim Sauer Sep 09 '20 at 17:40
  • @JoachimSauer Of course, and I said so on my previous comment. But you asked "how should the runtime know" -- it's not inconceivable and there are languages that do it. – Barmar Sep 09 '20 at 17:43
  • If the OP is a beginner with mathematical background, it's easy to understand why they would think `x = y` and `y = x` could be equivalent. – Barmar Sep 09 '20 at 17:44
  • @Barmar Yes, that's the logic I was following, thus why I couldn't understand how the same rules didn't apply in programming. – astralproject Sep 09 '20 at 17:46
  • @astralproject Because in most programming languages, you're telling the computer what to do, not just declaring relationships and letting it figure out how to achieve them. – Barmar Sep 09 '20 at 17:48
  • An assignment is not "these are equivalent", it's "take this and put it there". – Barmar Sep 09 '20 at 17:48
  • @astralproject: ask a mathematician what `x = x + 1` means and watch them squirm. A programmer interprets this quite differently (yes, there are exceptions ...). – Joachim Sauer Sep 09 '20 at 18:34

4 Answers4

1

When you call a function with new, this inside it will refer to the object being instantiated - for your code, that's Bob.

Using . references a property of an object, so

this.name = name;

assigns the value in the name variable name onto the name property of the Bob object being instantiated.

In contrast,

name = this.name;

assigns the value currently in the name property of the instantiated object to the name variable in scope. The instantiated object starts out empty, so this.name initially contains undefined. Assigning that value to the name variable sets it to undefined.

<Some Reference> = <Some Value>

puts <Some Value> into <Some Reference>.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
1

In the first version

function Person(age, name, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}

You're defining a constructor for a Person, which then returns the instance with the information you passed and set with this.thing

In the second version

function Person(age, name, gender) {
    name = this.name;
    age = this.age;
    gender = this.gender;
}

You're reassigning the variables inside, but never setting anything in the actual created object, therefore

name = this.name; // name = undefined, as this.name was never set
GMaiolo
  • 4,207
  • 1
  • 21
  • 37
0
function Person(age, name, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}

In your constructor the variables age, name and gender refer to the values given during instance creation.

eg. In:

Person p1 = new Person(21, "Bill", 'm')

The constructor receives age = 21, name = "Bill" and gender = 'm'

Within the constructor the this.name specifies that you're referring to the variable of the new instance (p1) of that class and not to the given values in the parameters.

So the given values are stored in the variables of the object p1.

Now if you try to copy the values of the variables of p1 (a newly created object) as is attempted in your second constructor, you'll obviously get an undefined error because no values have been added to the variables in p1 yet.

0
function Person(age, name, gender) {
 /*this "is pointing to this function(countructor fn) 
  so when you asign value to this.name  = name
  it takes the argument name and put it to this 
 object's name property
*/
    this.name = name;
    this.age = age;
    this.gender = gender;
}

in second version you are assigning value to argment " name" and setting it this.name which doesnt exist on the function (this) that's why new Person(24,"foo","male").name is undefined(you've not setted property name to that object you just asigned value to name argument)

function Person(age, name, gender) {

    name = this.name;
    age = this.age;
    gender = this.gender;
}
kavin
  • 16
  • 2