3

I'm trying to create a builder pattern in Javascript that uses private variables, while providing one public accessor (fullName) that returns a mashup of all the other properties. This question and answer suggests that I can use Object.defineProperty inside the person constructor in order to access private variables, but it doesn't work - instance.fullName is always undefined.

How can I get this working so that the builder pattern variables remain private, but the public accessor has access to them throughout the build chain?

var Person = function () {
    var _firstName, _lastName

    Object.defineProperty(this, "fullName", {
        get: function () {
            return _firstName + ' ' + _lastName;
        }
    });

    return {
        firstName: function (n) {
            _firstName = n
            return this
        },
        lastName: function (n) {
            _lastName = n
            return this
        }
    }
}

var x = new Person().firstName('bob').lastName('dole');

console.log(x.fullName); // always undefined
3
  • I suspect it's because the object being returned from Person is different from the this on which Object.defineProperty() is called. Commented Nov 27, 2015 at 19:38
  • Hmmmmm yeah, frankly Object.defineProperty() doesn't really feel like the right way to go about this anyway. Commented Nov 27, 2015 at 19:41
  • If I have to do it with public properties, that's fine, but even using this._firstName etc. doesn't work with this design. Commented Nov 27, 2015 at 19:48

1 Answer 1

3

As per my comment, change the object passed to defineProperty():

var Person = function () {
    var _firstName, _lastName

    var _self = {
        firstName: function (n) {
            _firstName = n
            return this
        },
        lastName: function (n) {
            _lastName = n
            return this
        }
    }

    Object.defineProperty(_self, "fullName", {
        get: function () {
            return _firstName + ' ' + _lastName;
        }
    });

    return _self;
}

var x = new Person().firstName('bob').lastName('dole');

console.log(x.fullName); // bob dole

http://jsfiddle.net/mattball/peztf9qs/

Sign up to request clarification or add additional context in comments.

1 Comment

HOT! Thanks a bunch. Makes sense.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.