【问题标题】:How to create and return a private object within a factory function?如何在工厂函数中创建和返回私有对象?
【发布时间】:2022-07-22 02:13:36
【问题描述】:
const module = (function() {
    let _priv = {a:1};
    return {
        get priv() {return _priv}
    }
})();

let obj = module.priv;

obj.b = 2;

console.log(module.priv); //{a:1, b:2}

使用工厂函数(或在这种情况下显示模块模式),我如何“获取”一个私有对象以供参考但使其不可变?

一个更实际的例子是井字游戏:

const gameBoard = (function() {
    let _board = (new Array(9)).fill(''); //want it to be immutable from the outside
    const add = (index,mark) => {
        _board[index] = mark;
    }
    const getBoard = () => {return _board}
    
    return {add, getBoard}
})();

我希望 _board 仅由 add() 方法更改,但我还希望在代码中的其他位置引用板的状态。但是使用这个当前代码,电路板是公开的并且可以更改。

【问题讨论】:

  • 使用Object.freeze冻结板子?
  • 要么首先Object.freeze(),要么在每次调用getBoard 时分发一份副本。
  • @Bergi 什么是只返回副本的好方法?
  • 返回{..._priv}_board.slice() 什么的

标签: javascript object module closures


【解决方案1】:

返回浅拷贝还不够吗?

所以而不是

{return _board}

你可以的

{return [..._board]}

所以在你的例子中看起来像这样

const gameBoard = (function() {
    let _board = (new Array(9)).fill(''); //want it to be immutable from the outside
    const add = (index,mark) => {
        _board[index] = mark;
    }
    const getBoard = () => {return [..._board]}
    
    return {add, getBoard, _board}
})();

console.log(gameBoard._board)
console.log(gameBoard.getBoard())
console.log(gameBoard._board === gameBoard.getBoard())

在运行代码时,您会看到 _board 和从 getBoard() 返回的数组没有引用同一个对象...所以更改数组,您会从使用 getBoard() 中得到对您的实际_board 有任何影响。

一旦您从返回中删除了 _board(我添加它以便能够在函数外部进行比较),我看不到从函数外部访问 _board 的方法

【讨论】:

    猜你喜欢
    • 2021-11-22
    • 1970-01-01
    • 2017-09-24
    • 2020-08-16
    • 2020-04-04
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多