UNPKG

just-safe-set

Version:

set value at property, create intermediate properties if necessary

64 lines (56 loc) 1.48 kB
var objectSafeSet = set; /* var obj1 = {}; set(obj1, 'a.aa.aaa', 4); // true obj1; // {a: {aa: {aaa: 4}}} var obj2 = {}; set(obj2, ['a', 'aa', 'aaa'], 4); // true obj2; // {a: {aa: {aaa: 4}}} var obj3 = {a: {aa: {aaa: 2}}}; set(obj3, 'a.aa.aaa', 3); // true obj3; // {a: {aa: {aaa: 3}}} const obj5 = {a: {}}; const sym = Symbol(); set(obj5.a, sym, 7); // true obj5; // {a: {Symbol(): 7}} */ function set(obj, propsArg, value) { var props, lastProp; if (Array.isArray(propsArg)) { props = propsArg.slice(0); } if (typeof propsArg == 'string') { props = propsArg.split('.'); } if (typeof propsArg == 'symbol') { props = [propsArg]; } if (!Array.isArray(props)) { throw new Error('props arg must be an array, a string or a symbol'); } lastProp = props.pop(); if (!lastProp) { return false; } prototypeCheck(lastProp); var thisProp; while ((thisProp = props.shift())) { prototypeCheck(thisProp); if (typeof obj[thisProp] == 'undefined') { obj[thisProp] = {}; } obj = obj[thisProp]; if (!obj || typeof obj != 'object') { return false; } } obj[lastProp] = value; return true; } function prototypeCheck(prop) { // coercion is intentional to catch prop values like `['__proto__']` if (prop == '__proto__' || prop == 'constructor' || prop == 'prototype') { throw new Error('setting of prototype values not supported'); } } export {objectSafeSet as default};