0

I want to know if there is a native way to downcast an object.

I mean, if I have an object like this: person1 = {name: 'Doe', age: 25};

And other like: person2 = {name: ''};

Is there someFunction that can be used to do something like: var person = somefunction(person2, person1); And get person = {name: 'Doe'}?

Or is there an approach with prototypes?

Thanks.

Mike Cluck
  • 31,869
  • 13
  • 80
  • 91
Josue Garcia
  • 1
  • 1
  • 1
  • 1
    Why do you even need to "downcast" it? Does it matter if the object has extra properties on it? – Mike Cluck May 31 '17 at 17:49
  • Yes, it matters. I am assigning a variable with the type defined by the IBM BPM Framework. If i have extra properties, it says that are not defined in the data type. – Josue Garcia May 31 '17 at 17:58
  • @JosueGarcia So the framework throws an error if there's extra data? If not, there's no reason to strip off the extra properties. If so, I've given an answer below. – Mike Cluck May 31 '17 at 18:02
  • This is homework isn't it. Because I've seen 2 or 3 identical questions in the last cpl days. I just can't find them w search. – James May 31 '17 at 18:16

4 Answers4

2

You could write a function which strips off extra properties from an object.

function removeExtraProperties(interf, obj) {
  let interfaceKeys = Object.keys(interf);
  for (let key in obj) {
    if (!obj.hasOwnProperty(key)) {
      // Make sure we don't strip off inherited properties
      // Remove this if you want to
      continue;
    }
    
    if (!interfaceKeys.includes(key)) {
      delete obj[key];
    }
  }
}

let person = { firstName: '' };
let bob = { firstName: 'Bob', lastName: 'Smith' };
removeExtraProperties(person, bob);
console.log(bob);
Mike Cluck
  • 31,869
  • 13
  • 80
  • 91
  • I would only discourage using `interface` as a parameter name as it is a *future reserved keyword* in JS. No real use cases AFAIK though, at least for now – nicholaswmin May 31 '17 at 18:06
0

Do you know the name of the properties you're looking to remove? If so, why not just delete the specific key off the object?

var person1 = {
  name: 'Doe',
  age: 25
};

delete person1['age'];

console.log(person1);
Woodrow
  • 2,740
  • 1
  • 14
  • 18
0

Sure, such a function exists:

function filterObj(p2, p1) {
  return Object.keys(p2).reduce(function (build, el) {
    build[el] = p1[el];
    return build;
  }, {});
}

person1 = {name: 'Doe', age: 25};
person2 = {name: ''};

console.log(filterObj(person2, person1));
James
  • 20,957
  • 5
  • 26
  • 41
0

I'm not really sure about the downcast concept, but for that I think I would use Object.assign(), using the enumerable property:

"use strict"

let person1 = { name: 'Doe', age: 25 }
let person2 = { name: '' }

for (let key in person1) {
  if (!person2.hasOwnProperty(key)) {
    Object.defineProperty(person1, key, { enumerable: false })
  }
}

let person = Object.assign(person2, person1)
console.log(person)   // { name: 'Doe' }

There is necessarily many ways to do this, as suggested in the other answers, and you can certainly make it a prototype if you need it that way.

edit:
I realize my first attempt was not very good at all as it change initial objects.
I take advantage of this to make it more simple:

let Person = function() {}
Person.prototype.downcast = function (p1, p2) {
  let c = {}
  for (let k in p1) {
    if (p2.hasOwnProperty(k)) {
      c[k] = p1[k]
    }
  }
  return c
}

let person = new Person().downcast(person1, person2)    
console.log(person)  // { name: 'Doe' }
TGrif
  • 5,725
  • 9
  • 31
  • 52