Converting C# class to JavaScript

Take a look at this basic class:

namespace AcmeWeb
{
    public string FirstName { get; set; }

    public class Person 
    {
        public Person(string firstName, string lastName) 
        {
            if (String.IsNullOrEmpty(firstName))
            {
                throw new ArgumentNullException(firstName);
            }

            this.FirstName = firstName;
        }
    }
}

What's the best translation of this into JavaScript?

This is what I'm thinking:

(function(namespace) {

    namespace.Person = function(firstName, lastName) {

        // Constructor

        (function() {
            if (!firstName) {
                throw "'firstName' argument cannot be null or empty";
            }
        })();

        // Private memberts

        var _ = {
            firstName: firstName
        };

        // Public members

        this.firstName = function(value) {
            if (typeof(value) === "undefined") {
                return _.firstName;
            }
            else {
                _.firstName = value;
                return this;
            }
        };

    };

})(AcmeWeb);

Upvotes: 6

Views: 6960

Answers (3)

Josiah Ruddell
Josiah Ruddell

Reputation: 29831

You could use real getters/setters in javascript. See John Resig's post for more information. See the fiddle.

(function(NS) {
    NS.Person = function(firstName, lastName) {
        if (!firstName) {
            throw "'firstName' argument cannot be null or empty";
        }

        var FirstName = firstName;
        this.__defineGetter__("FirstName", function(){
            console.log('FirstName getter says ' + FirstName);
            return FirstName;
        });

        this.__defineSetter__("FirstName", function(val){
            console.log('FirstName setter says ' + val);
            FirstName = val;
        });
    }
})(AcmeWeb);

var p = new AcmeWeb.Person('John', 'Smith');
p.FirstName;          // => FirstName getter says John
p.FirstName = 'Joe';  // => FirstName setter says Joe

Upvotes: 3

jAndy
jAndy

Reputation: 235962

It should be like

(function(namespace) {
    namespace.Person = function(firstName, lastName) {
        var firstName    = firstName || 'default',
            lastName     = lastName || 'default',
            moarPrivates = 'foo';

        return {
            firstname: function(value) {
                if( value ) {
                    firstName = value;
                    return this;
                }
                else {
                    return firstName;
                }
            },
            lastname: function(value) {
                if( value ) {
                    lastName = value;
                    return this;
                }
                else {
                    return lastName;
                }
            }
        };
    };
}(AcmeWeb));

var Andy = AcmeWeb.Person('Andy', 'Foo');

Andy.firstname('Andreas').lastname('Baaaaar');
console.log('Hello, my name is ', Andy.firstname(), ' ', Andy.lastname());

By returning on object literal, all local variables from the constructor function are closured. That is why they are private and only accessible from within the Person object. The public methods are those which you enclose into the returning object literal.

Example: http://www.jsfiddle.net/GkFu4/1/

Upvotes: 2

Emmett
Emmett

Reputation: 14327

var AcmeWeb = {
    Person: function(firstName, lastName) {
        if (!firstName) {
            throw "'firstName' argument cannot be null or empty";
        }
        this.FirstName = firstName;
    }
};

Then you can new up a Person:

var person = new AcmeWeb.Person("john", "smith");

Upvotes: 2

Related Questions