Caner Sezgin
Caner Sezgin

Reputation: 326

OOP Javascript - Getter & Setters

I have been studying some oop principles in javascript but I have some problems related to restriction of my code. In C# and Java we can easily do this kind of restrictions and see the results but in javascript I dont understand completely what is going on under the hood.

Anyway, I am trying to create a code that people can not change it outside basically. This is why I learnt that we should use local variables instead of creating object properties and by using getFunction as a method we can just read from outside.

Another approach is using "Object.defineProperty" (Getters & Setters)

All these work perfectly for primitive types but I guess we have some problem. I can not restrict my code read only. Without writing any setter methods I can change values because of the reference type feature. So how can I approach this problem ?

// Abstraction
function Circle(radius) {

this.radius = radius;

let defaultLocation = { x: 0, y: 0 };
let color = 'red';

this.getDefaultLocation = function() {
    return defaultLocation;
}

this.draw = function(){
    for (let key in defaultLocation) {
        console.log(key, defaultLocation[key]);
    }
    console.log('drawn');
};

// This can be changed from outside without set(){}
Object.defineProperty(this, 'defaultLocation', {
    get(){
        console.log('get function');
        return defaultLocation;
    }
});

// This needs set(){} to be changed
Object.defineProperty(this, 'color', {
    get(){
        console.log('get function');
        return color;
    },
    set(value){
        color = value;
    }
});
}

const circle = new Circle(10);

Upvotes: 4

Views: 1766

Answers (2)

Marvin
Marvin

Reputation: 953

You said

I am trying to create a code that people can not change it outside basically.

Refer to another stack overflow question. You can use the ES6 classes syntax, like so

class Circle {
    constructor(radius) {
        this.radius = radius;
    }

    get defaultLocation() {
        return { x: 0, y: 0 }; // Read-only
    }
    get color() {
        return 'red'; // Read-only
    }
}

let test = new Circle(2);
console.log(test.defaultLocation); // {x: 0, y: 0}
test.defaultLocation = 10; // No error but won't do anything
console.log(test.defaultLocation); // {x: 0, y: 0}

Upvotes: 2

user5063151
user5063151

Reputation:

If you only want a only a get() function, you can use a constructor function (not the latest ECMAScript syntax) with block-scope (let) variables being private instance variables. The key is NOT to use the this keyword.

function Circle(r = 0) {

    // Private
    let raduis = r


    // Public
    this.getRaduis = function() {

      return raduis
    }

}

let circle = new Circle(1)

console.log(circle.getRaduis())
console.log(circle.raduis)

Output:

1
undefined

You can add another option to defineProperty. This effectively creates a final static constant. Just set writeable = false.

Object.defineProperty(Circle, 'constants', {

  value : {

    constant  : 0,
    operation : () => {

      console.log('Some non-primitive')
    }
  },

  writable     : false,
  enumerable   : false,
  configurable : false
});

Circle.constants.operation()

Output:

Some non-primitive

See the "Writable attribute" section of the documentation.

Upvotes: 2

Related Questions