Javascript OOP getter函数应返回私有属性的值或引用

Javascript OOP getter函数应返回私有属性的值或引用,javascript,Javascript,私有属性的getter是否应返回对属性或属性值的引用(如果属性是对象,则返回克隆)。如果属性具有基元类型(字符串、数字、布尔值)或对不可变对象的引用(string,number),答案是您直接返回值/引用,因为调用者无法使用它来更改对象的状态 如果属性具有对可变对象的引用类型(数组、对象、日期、批次和许多其他内容),则取决于您是否希望调用方能够更改对象副本上的属性。如果是,请返回引用。如果没有,请克隆它 例如,让我们假设一个具有私有数组的对象以及可以在该数组上执行的一些操作: var obj =

私有属性的getter是否应返回对属性或属性值的引用(如果属性是对象,则返回克隆)。

如果属性具有基元类型(字符串、数字、布尔值)或对不可变对象的引用(
string
number
),答案是您直接返回值/引用,因为调用者无法使用它来更改对象的状态

如果属性具有对可变对象的引用类型(数组、
对象
日期
、批次和许多其他内容),则取决于您是否希望调用方能够更改对象副本上的属性。如果是,请返回引用。如果没有,请克隆它

例如,让我们假设一个具有私有数组的对象以及可以在该数组上执行的一些操作:

var obj = (function() {
    var o = {};
    var theArray = [];

    o.addItem = function(item) {
        theArray.push(item);
    };

    o.getItemAt = function(index) {
        return theArray[index];
    };

    return o;
})();
(请注意,这并不是一个出色的对象设计示例。:-)

现在您需要添加一个
getArray
操作。您可以通过两种方式实现这一点:

您可以返回对数组的引用:

o.getArray = function() {
    return theArray;
};
o.getArray = function() {
    return theArray.slice(0);
};
…这意味着调用方可以对其执行各种操作(如从中删除项,这是对象以前不支持的操作),从而更改对象的状态(因为您已授予它们对以前私有数组的直接访问权限)

或者,您可以返回阵列的克隆:

o.getArray = function() {
    return theArray;
};
o.getArray = function() {
    return theArray.slice(0);
};

…这意味着调用者无法对私有数组执行任何操作,他们只能对您提供给他们的私有数组副本进行操作。

如果属性具有基元类型(字符串、数字、布尔值)或对不可变对象的引用(
string
number
),答案是直接返回值/引用,因为调用者无法改变对象的状态

如果属性具有对可变对象的引用类型(数组、
对象
日期
、批次和许多其他内容),则取决于您是否希望调用方能够更改对象副本上的属性。如果是,请返回引用。如果没有,请克隆它

例如,让我们假设一个具有私有数组的对象以及可以在该数组上执行的一些操作:

var obj = (function() {
    var o = {};
    var theArray = [];

    o.addItem = function(item) {
        theArray.push(item);
    };

    o.getItemAt = function(index) {
        return theArray[index];
    };

    return o;
})();
(请注意,这并不是一个出色的对象设计示例。:-)

现在您需要添加一个
getArray
操作。您可以通过两种方式实现这一点:

您可以返回对数组的引用:

o.getArray = function() {
    return theArray;
};
o.getArray = function() {
    return theArray.slice(0);
};
…这意味着调用方可以对其执行各种操作(如从中删除项,这是对象以前不支持的操作),从而更改对象的状态(因为您已授予它们对以前私有数组的直接访问权限)

或者,您可以返回阵列的克隆:

o.getArray = function() {
    return theArray;
};
o.getArray = function() {
    return theArray.slice(0);
};

…这意味着调用方不能对私有数组执行任何操作,他们只能对您提供给他们的数组副本进行操作。

这取决于私有属性是否不可变。如果它是不可变的,它就不能被改变,返回它也没有坏处。然而,如果它是可变的,那么返回它将打破信息隐藏的OOP原则

如果它是一个原语不可变的int/number,那么返回私有属性就可以了,因为它实现了两件事:

  • 隐藏私有属性并提供接口,对私有属性实现的任何更改都不会轻易破坏接口
  • 调用方无法更改返回的对象(在本例中为值),因为它是一个基本类型,并且是按值传递的
但是,如果您从方法返回一个可变数组,并且您的语言通过引用传递对象,那么您必须接受这样一个事实,即调用方可能决定更改此内部对象,这很容易导致内部代码中断


出于这些原因,如果您计划将副本返回到可变对象,请返回副本而不是基础对象本身。

这取决于私有属性是否不可变。如果它是不可变的,它就不能被改变,返回它也没有坏处。然而,如果它是可变的,那么返回它将打破信息隐藏的OOP原则

如果它是一个原语不可变的int/number,那么返回私有属性就可以了,因为它实现了两件事:

  • 隐藏私有属性并提供接口,对私有属性实现的任何更改都不会轻易破坏接口
  • 调用方无法更改返回的对象(在本例中为值),因为它是一个基本类型,并且是按值传递的
但是,如果您从方法返回一个可变数组,并且您的语言通过引用传递对象,那么您必须接受这样一个事实,即调用方可能决定更改此内部对象,这很容易导致内部代码中断


由于这些原因,如果您计划将副本返回到可变对象,请返回副本而不是基础对象本身。

通常,无论在何处使用属性,都不能更改属性值。这符合OOP的重要原则,即封装。

通常,无论在何处使用属性,都不能更改属性值。这满足了OOP的重要原则,即封装