LoginSignup
1
0

More than 5 years have passed since last update.

deepFreeze(カスタマイズ版)をlodash非依存にする

Last updated at Posted at 2017-03-03

ES6のconstを使い倒すレシピ2 - Object.freeze編 〜 JSおくのほそ道 #035 - Qiita
http://qiita.com/hosomichi/items/84b05c1b0c09d26cd11e

という記事には

MDNのObject.freezeページにもこのこのことに言及しており、子属性の凍結を汎用的に行えるdeepFreezeなる関数を提示してくれています。
ところがこのdeepFreezeは引数となるオブジェクト自体をfreezeして書き換えてしまい、新しいオブジェクトを返してくれるでもなかったので、ちょっと自分が使う用に書き換えてみました。一部lodashを使っています。

deepFreeze(カスタマイズ版)
const _ = require('lodash');

function deepFreeze(o) {
  const oFrz = _.clone(o);
  _.keys(oFrz).forEach(key => {
    if (oFrz.hasOwnProperty(key) && (typeof oFrz[key] === "object") && !Object.isFrozen(oFrz[key])) {
      oFrz[key] = deepFreeze(oFrz[key]);
    }
  });
  return Object.freeze(oFrz);
}

という記述があります。ところが

Lodash/Underscoreは必要ない(かも) - Qiita
http://qiita.com/ossan-engineer/items/ad5313d84da82c6ac421#_keys

にもあるように、lodashはいらない気がします。無駄な依存はどんどん消しましょう。

_.clone()

javascript - ES6 equivalent to lodash _.clone (lodash failing to clone ES6 Proxy) - Stack Overflow
http://stackoverflow.com/questions/38215982/es6-equivalent-to-lodash-clone-lodash-failing-to-clone-es6-proxy

Using ES6 Object.assign appears is a substitute for _.clone.

var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }

It also appears to successfully clone a ES6 proxy, for which lodash failed and returned an "undefined"

というわけで、Object.assignを使えば置き換えられます。

Chrome Firefox IE Edge Opera Safari
5✔ 4.0 ✔ 12 5

困るのがIE11で、IE11だけはまだ多くのところでサポートを切れないかと思います。

sindresorhus/object-assign: ES2015 Object.assign() ponyfill
にPolyfillがあり、MDNにも記載があります。のでそれを使う話になるかと思います。

_.keys

オブジェクト自身の列挙可能なプロパティの全ての名前を取得します。

// Underscore/Lodash
var result = _.keys({one: 1, two: 2, three: 3});
console.log(result);
// output: ["one", "two", "three"]
// Native
var result2 = Object.keys({one: 1, two: 2, three: 3});
console.log(result2);
// output: ["one", "two", "three"]
Chrome Firefox IE Edge Opera Safari
5✔ 4.0 ✔ 9 12 5

結論

IE11を無視すると

//http://qiita.com/hosomichi/items/84b05c1b0c09d26cd11e
//https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
const deepFreeze = (o) => {
    const oFrz = Object.assign({}, o);
    Object.keys(oFrz).forEach((key) => {
        if (oFrz.hasOwnProperty(key) && (typeof oFrz[key] === "object") && !Object.isFrozen(oFrz[key])) {
        oFrz[key] = deepFreeze(oFrz[key]);
        }
    });
    return Object.freeze(oFrz);
}

このようになる。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0