Question

I am familiar with strongly typed OOP language such as C# and Java, so I am a little confused with Javascript. I want my class to be encapsulated, for example:

function Human() {
    var _name = '';
    var _nameChangeCounter = 0;
}

Human.constructor = Human;
Human.prototype = Object.create(Animal);

As you can see, Human extends the Animal class. Now I need a getter and setter for Name, and a getter for NameChangeCounter. In the setter of Name, it should increase the NameChangeCounter. I looked up how to make getter and setter in Javascript in this question:

Name.prototype = {
    get fullName() {
        return this.first + " " + this.last;
    },

    set fullName(name) {
        var names = name.split(" ");
        this.first = names[0];
        this.last = names[1];
    }
};

However, now that prototype is taken for inheritance, how can I do it? Do I have to do the Java-style (create getName, setName, getNameChangeCounter functions)? How do properties like window.location.href implemented?

Was it helpful?

Solution 2

Found this function on mdn: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Summary

Here is an example fiddle: http://jsfiddle.net/EfyCX/1/

And here is some javascript for getters and setters using Object.defineProperties

Object.defineProperties(Person.prototype, {
    "name": {
        get: function() { return this._name },
        set: function(name) { 
            this.changeCount++
            this._name = name
        }
    }
})

OTHER TIPS

This works for me:

function Name(){
    this.first = '';
    this.last = '';
}

Name.prototype.getFullName = function() {
    return this.first + ' ' + this.last;
}

Name.prototype.setFullName = function(fullName){
    var names = fullName.split(" ");
    this.first = names[0];
    this.last = names[1];
}


function Human() {
    var name = new Name(), 
        counter = 0;
    Object.defineProperty(this, 'name', {
        configurable: true,
        enumerable: true,
        get: function(){
            return name;
        },
        set: function(fullName){
            name.setFullName(fullName);
        }
    });
    Object.defineProperty(this, 'counter', {
        configurable:true,
        enumerable: true,
        get: function(){
            return counter;
        },
        set: function(value){
            counter = value;
        }
    });
}

var luke = new Human();
luke.name = 'Luke Skywalker';

console.log(luke.name.first); //Luke
console.log(luke.name.last); //Skywalker
console.log(luke.name.getFullName()); //Luke Skywalker
console.log(luke.name); //Object

luke.name = 'Peter Parker';
console.log(luke.name.first); //Peter
console.log(luke.name.last); //Parker
console.log(luke.name.getFullName()); //Peter Parker

You're trying to use a classical inheritance in a prototype based language. In javascript there are no Class definitions and Class instances. There are only static objects, that share methods through a prototype chain.

To make objects that inherit from Animal:

var Animal = {vertebrae: "jelly"};
var Human = Object.create(Animal)

console.log(Human.vertebrae); //=> jelly

To make objects that inherit from Human

var programmer = Object.create(Human);
console.log(programmer.vertebrae); //=> jelly

Some JS authorities (mainly Crockford) discourage overriding the standard get and set methods, unless you absolutely know what you're doing.

Also important to note that JS does not have private properties, and that functionality can be achieved by use of an outer function scope and closure. Search for javascript private properties.

To add methods to Human

Human._name = 'Human';
Human.getName = function(){ return this._name; }
Human.setName = function(val){ this._name = val; }

console.log(programmer.getName()); //=> 'Human'

programmer.setName("Bob");
console.log(programmer.getName()); //=> 'Bob'
console.log(Human.getName()); //=> 'Human'
console.log(Animal.getName()); //=> not a function

you can use the properties object if you like to set the methods when doing Object.create(), but that syntax is unfortunately verbose.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top