OOP Javascript - Getter & 二传手

OOP Javascript - Getter & Setters

我一直在研究 javascript 中的一些 oop 原理,但我遇到了一些与我的代码限制有关的问题。在 C# 和 Java 中,我们可以轻松地执行此类限制并查看结果,但在 javascript 中,我不完全理解幕后发生的事情。

无论如何,我正在尝试创建一个人们基本上无法在外部更改的代码。这就是为什么我了解到我们应该使用局部变量而不是创建对象属性,并且通过使用 getFunction 作为我们可以从外部读取的方法。

另一种方法是使用 "Object.defineProperty" (Getters & Setters)

所有这些对于基本类型都非常有效,但我想我们遇到了一些问题。我不能限制我的代码只读。由于引用类型功能,我无需编写任何 setter 方法即可更改值。那么我该如何解决这个问题呢?

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

如果您只想要一个 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

请参阅 documentation 的 "Writable attribute" 部分。

你说

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

参考another stack overflow question。你可以使用 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}