KidCode
KidCode

Reputation: 4201

Javascript Setter not setting additional property value

I'm playing with Javascript getters and setters and I can't seem to set the value of an additional property from inside a setter:

'use strict';

var lastUserId = 0;

function getNewUserId()
{
    var id = lastUserId;
    lastUserId++;
    return id;
}

function User(_name, _email, _password)
{
    this.Name = _name;
    this.Email = _email;
    this.Id = getNewUserId();

    //Make the Id read-only
    Object.defineProperty(this, 'Id', {writable: false});

    //Test changing the Id - Should get a read-only error.
    //this.Id = 12;

    this.PasswordHash = -1; //Inital value
    var PasswordValue;


    Object.defineProperty(User, "Password",
    {
        configurable: true,
        get: function() {
            return this.PasswordValue;
        },
        set : function(value) {
            this.PasswordHash = hashCode(value);
            this.PasswordValue = value;
        }
    });

    this.Password = _password;
    //this.PasswordHash = "thisWorks";
}

function hashCode (val) {
    var hash = 0, i, chr, len;
    if (val.length === 0) return hash;
    for (i = 0, len = val.length; i < len; i++) {
        chr   = val.charCodeAt(i);
        hash  = ((hash << 5) - hash) + chr;
        hash |= 0; // Convert to 32bit integer
    }
    return hash;
};

When I create a new instance of the User object, I'm expecting the PasswordHash to be set via the PasswordValue setter, however checking the value of PasswordHash after instantiation returns -1 (The initial value for the property). - Checking the value of Password returns the correct value, based on whatever I passed in as the _password parameter.

I've also tried implementing PasswordHash in the same way as PasswordValue (i.e with a getter / setter and a backing member), but this returns the same result.

What am I missing?

Note: this obviously isn't production code, I'm just exploring some areas of JS I haven't used before!

Upvotes: 1

Views: 530

Answers (1)

Fan Jin
Fan Jin

Reputation: 2460

You need to call this inside Object.defineProperty(User, "Password",. I modified you code a little bit, it is now working.

'use strict';

var lastUserId = 0;

function getNewUserId()
{
    var id = lastUserId;
    lastUserId++;
    return id;
}
var User = function(_name, _email, _password) {
  this.Name = _name;
  this.Email = _email;
  
  this.Id = getNewUserId();
  //Make the Id read-only
  Object.defineProperty(this, 'Id', {writable: false});
  Object.defineProperty(this, "Password", {
        configurable: true,
        get: function() {
            return this.PasswordValue;
        },
        set : function(value) {
            this.PasswordHash = hashCode(value);
            this.PasswordValue = value;
        }
  });
  this.Password = _password;
}
    


function hashCode (val) {
    var hash = 0, i, chr, len;
    if (val.length === 0) return hash;
    for (i = 0, len = val.length; i < len; i++) {
        chr   = val.charCodeAt(i);
        hash  = ((hash << 5) - hash) + chr;
        hash |= 0; // Convert to 32bit integer
    }
    return hash;
};

var u = new User("Fan", "[email protected]", "123456");
console.log(u.PasswordHash);

Upvotes: 2

Related Questions