Tell me why the trace code does not display the changed name and age?

var person = (function (name, age) {  var  $name = name,    $age = age;   return {  name: $name,  age: $age,   setName: function (name) { $name = name;},   setAge: function (age) { $age = age;}  };  })('Gregory', 42);  person.setName('Miller'); person.setAge(30);  console.log(person.name); console.log(person.age); 

Exhaust:

 Gregory 42 

    3 answers 3

    The problem is that the setters change local variables that are not obtained anywhere else.

    The values ​​of the name and age fields are set once and then not changed.

    For corrections, you can use getters instead of fields.

     var person = (function(name, age) { var  $name = name,    $age = age;  return { get name() { return $name },  get age() { return $age },   setName: function(name) { $name = name; },    setAge: function(age) { $age = age; } }; })('Gregory', 42); person.setName('Miller'); person.setAge(30); console.log(person.name); console.log(person.age); 

    Or change the object fields directly

     var person = (function(name, age) { return { name: name, age: age, setName: function(name) { this.name = name; }, setAge: function(age) { this.age = age; } }; })('Gregory', 42); person.setName('Miller'); person.setAge(30); console.log(person.name); console.log(person.age); 

    but in this case it is worth monitoring the possible loss of the call context

    • those. How do I understand what is returned in the name and age are the person fields? not $ name, $ age? - Cfon
    • @Cfon, exactly, your function returned the object, initializing its fields and, in fact, it was all over - Grundy
    • And I understood everything! Thank! - Cfon

    The solution through the class, in my opinion, is clearer and there is a great opportunity for expansion

     class Person { constructor (name, age) { this.name = name; this.age = age; }; setName (name) { this.name = name; }; setAge (age) { this.age = age; }; } let person = new Person ('Gregory', 42); person.setName('Miller'); person.setAge(30); console.log(person.name); console.log(person.age); 
    • not sure if this is javascript;) and will it work everywhere? - Cfon
    • This solution complies with ES6 :) All modern browsers support this standard) - Aliaksandr Pitkevich
    • I myself am a positive speaker, but recently hooked on JavaScript, precisely because of a non-standard approach to objects;) - Cfon
    • @Cfon my solution above demonstrates OOP in a prototype style using the new standard, but do you agree, the solution looks simpler?) - Aliaksandr Pitkevich
    • Thanks, I just study JavaScript on the book “Development of one-page web applications. M. Mikowski, J. Powell, 2014” is not written about it :) - Cfon

     var person = (function (name, age) { var $name = name, $age = age; return { name: $name, age: $age, setName: function (name) { this.name = name;}, setAge: function (age) { this.age = age;} }; })('Gregory', 42); person.setName('Miller'); person.setAge(30); console.log(person.name); console.log(person.age); 

    • original;)) - Cfon
    • my mistake was that I thought like a C ++ programmer, as I later understood the return statement returns an object with its attributes and functions, I thought that the attributes passed references to $ function and $ age function variables. - Cfon