ООП Javascript - добытчик и сеттеры - PullRequest
0 голосов
/ 26 августа 2018

Я изучал некоторые основные принципы в javascript, но у меня есть некоторые проблемы, связанные с ограничением моего кода. В C # и Java мы можем легко сделать такого рода ограничения и увидеть результаты, но в javascript я не совсем понимаю, что происходит под капотом.

Во всяком случае, я пытаюсь создать код, чтобы люди не могли изменить его снаружи. Вот почему я узнал, что мы должны использовать локальные переменные вместо создания свойств объекта и использования getFunction в качестве метода, который мы можем просто читать извне.

Другой подход - использование "Object.defineProperty" (методы получения и установки)

Все это прекрасно работает для примитивных типов, но я думаю, у нас есть некоторые проблемы. Я не могу ограничить свой код только для чтения. Без написания каких-либо методов установки я могу изменить значения из-за функции ссылочного типа. Итак, как я могу подойти к этой проблеме?

// 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);

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Вы сказали

Я пытаюсь создать код, чтобы люди не могли его изменить снаружи.

См. другой вопрос переполнения стека .Вы можете использовать синтаксис классов ES6, например,

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}
0 голосов
/ 26 августа 2018

Если вам нужна только функция get(), вы можете использовать функцию конструктора (не последний синтаксис ECMAScript) с переменными блочной области (let), которые являются частными переменными экземпляра. Ключ NOT для использования ключевого слова this.

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)

Выход:

1
undefined

Вы можете добавить еще одну опцию к defineProperty. Это эффективно создает final static константу. Просто установите writeable = false.

Object.defineProperty(Circle, 'constants', {

  value : {

    constant  : 0,
    operation : () => {

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

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

Circle.constants.operation()

Выход:

Some non-primitive

См. Раздел «Атрибут записи» документации .

...