src/store.js
function deepFreeze(obj) {
    // if it's already frozen, don't bother going deep into it...
    if (obj === null || typeof obj === 'undefined' || typeof obj.toJS === 'function' || typeof obj !== 'object') {
        return obj;
    }

    // Retrieve the property names defined on obj
    let propNames = Object.getOwnPropertyNames(obj);
    let properties = {toJS: {value: mirror.bind(obj)}};

    if (Array.isArray(obj)) {
        // create a copy and deep freeze all entries
        obj = obj.slice(0).map(deepFreeze);
        // re-attach some important methods
        ['map', 'forEach', 'find', 'indexOf', 'filter', 'some', 'every', 'lastIndexOf', 'slice'].forEach(fn => {
            properties[fn] = {value: function () { return deepFreeze(Array.prototype[fn].apply(obj, arguments));}};
        });
    }

    // Freeze properties before freezing self
    for (let index = 0, prop; prop = obj[propNames[index]], index < propNames.length; index += 1) {
        // Freeze prop if it is an object
        properties[propNames[index]] = {
            enumerable: true,
            get () {
                return deepFreeze(prop);
            },
            set (newValue) {
                throw new Error('Cannot change property "' + propNames[index] + '" to "' + newValue + '" of an immutable object');
            }
        }
    }

    // Freeze self (no-op if already frozen)
    return Object.freeze(Object.create(Object.getPrototypeOf(obj), properties));
}
function deepFreeze(obj) {
    // if it's already frozen, don't bother going deep into it...
    if (obj === null || typeof obj === 'undefined' || typeof obj.toJS === 'function' || typeof obj !== 'object') {
        return obj;
    }

    // Retrieve the property names defined on obj
    let propNames = Object.getOwnPropertyNames(obj);
    let properties = {toJS: {value: mirror.bind(obj)}};

    if (Array.isArray(obj)) {
        // create a copy and deep freeze all entries
        obj = obj.slice(0).map(deepFreeze);
        // re-attach some important methods
        ['map', 'forEach', 'find', 'indexOf', 'filter', 'some', 'every', 'lastIndexOf', 'slice'].forEach(fn => {
            properties[fn] = {value: function () { return deepFreeze(Array.prototype[fn].apply(obj, arguments));}};
        });
    }

    // Freeze properties before freezing self
    for (let index = 0, prop; prop = obj[propNames[index]], index < propNames.length; index += 1) {
        // Freeze prop if it is an object
        properties[propNames[index]] = {
            enumerable: true,
            get () {
                return deepFreeze(prop);
            },
            set (newValue) {
                throw new Error('Cannot change property "' + propNames[index] + '" to "' + newValue + '" of an immutable object');
            }
        }
    }

    // Freeze self (no-op if already frozen)
    return Object.freeze(Object.create(Object.getPrototypeOf(obj), properties));
}
function deepFreeze ( obj ) { // if it's already frozen, don't bother going deep into it... if ( obj === null || typeof obj === 'undefined' || typeof obj . toJS === 'function' || typeof obj !== 'object' ) { return obj ; } // Retrieve the property names defined on obj let propNames = Object . getOwnPropertyNames ( obj ) ; let properties = { toJS : { value : mirror . bind ( obj ) } } ; if ( Array . isArray ( obj ) ) { // create a copy and deep freeze all entries obj = obj . slice ( 0 ) . map ( deepFreeze ) ; // re-attach some important methods [ 'map' , 'forEach' , 'find' , 'indexOf' , 'filter' , 'some' , 'every' , 'lastIndexOf' , 'slice' ] . forEach ( fn => { properties [ fn ] = { value : function ( ) { return deepFreeze ( Array . prototype [ fn ] . apply ( obj , arguments ) ) ; } } ; } ) ; } // Freeze properties before freezing self for ( let index = 0 , prop ; prop = obj [ propNames [ index ] ] , index < propNames . length ; index += 1 ) { // Freeze prop if it is an object properties [ propNames [ index ] ] = { enumerable : true , get ( ) { return deepFreeze ( prop ) ; } , set ( newValue ) { throw new Error ( 'Cannot change property "' + propNames [ index ] + '" to "' + newValue + '" of an immutable object' ) ; } } } // Freeze self (no-op if already frozen) return Object . freeze ( Object . create ( Object . getPrototypeOf ( obj ) , properties ) ) ; }
Create an immutable object lazily.
@param {Object} obj
@returns {Object} the immutable object created
Create an immutable object lazily .