ES6のconstを使い倒すレシピ2 - Object.freeze編 〜 JSおくのほそ道 #035 - Qiita
http://qiita.com/hosomichi/items/84b05c1b0c09d26cd11e
という記事には
MDNのObject.freezeページにもこのこのことに言及しており、子属性の凍結を汎用的に行えるdeepFreezeなる関数を提示してくれています。
ところがこのdeepFreezeは引数となるオブジェクト自体をfreezeして書き換えてしまい、新しいオブジェクトを返してくれるでもなかったので、ちょっと自分が使う用に書き換えてみました。一部lodashを使っています。
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を使えば置き換えられます。
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
---|---|---|---|---|---|
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"]
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
---|---|---|---|---|---|
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);
}
このようになる。