1

My goal is to have otherFoo inherit from foo, but then not inherit back up to the parent. I've tried a few angles with Object.create but it keeps inheriting back to the parent.

var foo = { "bar": {"data1":"02", "data2":"03"}, "otherBar":"09"};

var otherFoo = {};
otherFoo.bar = foo.bar;
otherFoo.bar.data1 = "04";

I want the end result to be

// foo = { "bar": {"data1":"02", "data2":"03"}};
// otherFoo = { "bar": {"data1":"04", "data2":"03"}};

Here is a JSFiddle for Convenience

lando2319
  • 1,509
  • 1
  • 19
  • 27
  • You mean "copy" the object? – Patrick Roberts Jan 26 '18 at 00:39
  • I just updated it, I'm intending to copy just `bar` not `otherBar` – lando2319 Jan 26 '18 at 00:42
  • References man. References. I'm to lazy can someone find the duplicate for this question. – Darkrum Jan 26 '18 at 00:43
  • Another way to accomplish the same goal: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new – simon Jan 26 '18 at 00:46
  • Inherit? You mean like `otherFoo = Object.create(foo); otherFoo.bar = Object.create(foo.bar);`? Have a look at [this question](https://stackoverflow.com/questions/10131052/crockfords-prototypal-inheritance-issues-with-nested-objects/) – Bergi Jan 31 '18 at 21:11

5 Answers5

3

Do you mean Object.assign() ?

let foo = { "bar": {"data1":"02", "data2":"03"}, "otherBar":"09"};

let otherFoo = Object.assign({}, foo);

foo.otherBar = 10;

console.log(foo);
console.log(otherFoo);
Fabien Greard
  • 1,854
  • 1
  • 16
  • 26
1

You could try using a class:

function template(data1) {
    this.data = { "bar": {"data1": typeof data1 !== 'undefined' ? data1: '02', "data2":"03"}};
}
var foo = new template();
var otherFoo = new template('04');
console.log(foo.data);
console.log(otherFoo.data);
Talha
  • 807
  • 9
  • 13
0

If you can use Object spread operator:

var foo = { "bar": {"data1":"02", "data2":"03"}, "otherBar":"09"};

var { otherBar, ...bar } = foo
foo = bar
var fooBar = {
    bar: { ...foo.bar, data2: "04" }
}

Otherwise you need a deep clone of your object.

  • This isn't ES6, this is currently [a stage 3 ECMAScript proposal](https://github.com/tc39/proposal-object-rest-spread), and is not implemented. – Patrick Roberts Jan 26 '18 at 01:23
0

Close to Talha's answer, but figured i'd just go ahead and post it (as it mimicks your example almost exactly above on what you want the data represented like)

const bar = function(data){
  this.bar = data;
}

let foo = new bar({"data1":"02", "data2":"03"})
let otherFoo = new bar({"data1":"04", "data2":"03"})
console.log(foo)
console.log(otherFoo)
simon
  • 854
  • 1
  • 9
  • 23
0

Here's a function that can deep clone any object, including cyclical objects. It also maintains cyclical references as they are in the original object, without referencing any values from the original, except for values in the prototype chain:

function clone (object, objects = new WeakMap()) {
  // this will omit copying primitives
  if (typeof object !== 'object' && typeof object !== 'function' || object === null) {
    return object;
  }

  if (objects.has(object)) {
    return objects.get(object);
  }

  const proto = Object.getPrototypeOf(object);
  const descriptors = Object.getOwnPropertyDescriptors(object);
  const copy = typeof object === 'function'
    ? object.call.bind(object)
    : Object.create(proto);

  objects.set(object, copy);

  Object.values(descriptors).forEach(descriptor => {
    if ('value' in descriptor) {
      descriptor.value = clone(descriptor.value, objects);
    }
  });

  return Object.defineProperties(copy, descriptors);
}

let foo = { bar: { data1: '02', data2: '03' }, otherBar: '09' };

class Test {
  constructor (...args) { this.args = args; }
  cool () { return 'feature'; }
}

foo.bar.foo = foo;
foo.bar.bar = foo.bar;
foo.test = new Test('foo', 'bar');
foo.bar.test = foo.test;
foo.bar.func = () => 'func';

console.log(foo);

var otherFoo = clone(foo);

// everything copies as expected
console.log(otherFoo);
console.log(otherFoo.test instanceof Test);
console.log(otherFoo.bar.func() === 'func');
console.log(typeof otherFoo.bar.func === 'function');
// nothing references the original object
console.log(foo !== otherFoo);
console.log(foo.bar !== otherFoo.bar);
console.log(foo.test !== otherFoo.test);
console.log(foo.bar.func !== otherFoo.bar.func);
// doesn't copy prototypes
console.log(foo.test.cool === otherFoo.test.cool);
.as-console-wrapper{max-height:100%!important}
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153