3

プロパティを変更できないオブジェクトの読み取り専用/不変バージョンを JavaScript で作成するにはどうすればよいですか? これは、サブオブジェクトなどのプロパティにも適用する必要があります。

これを行うために遭遇したすべてのメソッド ( Object.definePropertyObject.freezeなど) は、オブジェクトの最上位のプロパティに対してのみ機能し、サブオブジェクトに対しては機能しません。

(考えられるユースケース:特定のモジュールでsettingsまたはconfiguration型オブジェクトを作成/変更した後、不変形式でプログラムの残りのモジュールに公開する必要があります。)

4

3 に答える 3

6

色々考えた末にたどり着いた解決策です。私のニーズにうまく機能するので、QnA スタイルで共有したいと思います。改善点や問題点を見つけた場合は、提案してください。

/**
 * Make the the specified object (deeply) immutable or "read-only", so that none of its
 * properties (or sub-properties) can be modified. The converted object is returned.
 * @param {object} obj Input object
 */
makeImmutable: function makeImmutable (obj) {
    if ((typeof obj === "object" && obj !== null) ||
        (Array.isArray? Array.isArray(obj): obj instanceof Array) ||
        (typeof obj === "function")) {

        Object.freeze(obj);

        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                makeImmutable(obj[key]);
            }
        }
    }
    return obj;
}

編集: コードを簡略化しました。また、配列を正しく処理するようになりました。

于 2013-04-17T15:28:34.207 に答える
0

すでに素晴らしい答えです。これは使用していlodashます:

var _ = require('lodash');

オブジェクトを不変にするには:

/**
 * Makes an Object immutable by (deep) freezing all own peoperties.
 * @param {*} obj - Object to make immutable.
 * @returns {*} The input Object.
 */
function deepFreeze(obj) {
    if (_.isObject(obj) || _.isArray(obj) || _.isFunction(obj)) {
        Object.freeze(obj);
        _.forOwn(obj, deepFreeze);
    }
    return obj;
}

不変のクローンを作成するには:

var frozenClone = deepFreeze(_.cloneDeep(obj));
于 2016-09-16T09:05:36.393 に答える