1

I need to create an object that holds properties of birds. I then need to be able to use object methods to add new values to this object, without the methods being inside the object. I've been able to output what I'm supposed to, BUT only with the object methods inside the object. I'm don't know how I can apply an object outside of the object, to the properties within the object?

function Bird(species, color, locations) {
  let birdObject = {    species : species,
    color : color,
    locations : locations,
    getColor : function() {
      return this.color;
    },
    setColor : function(newColor) {
      this.color = newColor;
    },
    addLocation : function(newLocation) {
      this.locations.push(newLocation);
    },
    getLocations : function() {
      return this.locations;
    }
  }
  return(birdObject);
}

const newBird = Bird('canary', 'red', ['newyork', 'spain'])

console.log(newBird)
console.log(newBird.getColor());
newBird.setColor('yellow');
console.log(newBird.getColor());
newBird.addLocation('france');
console.log(newBird.getLocations())
kidnoj
  • 21
  • 2
  • What I've tried so far has been (using getColor as an example): - Initializing a function getColor() outside of the object, but inside function Bird, returning birdObject.color, but the error message is that newBird.getColor isn't a function - I tried creating separate functions for each method that was required, but then I didn't know how to reference the original object inside Bird object – kidnoj Oct 10 '22 at 01:17
  • so, you want the methods, like getColor, setColor, etc to work like `newBird.getColor()` but you don't want `getColor` to be a method of `newBird`? – Jaromanda X Oct 10 '22 at 01:17
  • @JaromandaX Yes! Exactly it; but everything I do either says that it's not a function, or it just fails. I don't know how to word my search online to see if I can learn the concept for it. – kidnoj Oct 10 '22 at 01:20
  • 1
    This sounds like a very odd requirement? Is this a homework question? I think what you're looking for is [Function.prototype.call()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call) – Phil Oct 10 '22 at 01:23
  • 2
    Why do you need to do this? What are you trying to achieve? – Pointy Oct 10 '22 at 01:29
  • if you want to use the functions like `newBird.getColor()` then they must be properties of `newBird` - stands to reason since `x.y` accesses the `y` property of `x` and nothing else – Jaromanda X Oct 10 '22 at 01:42
  • 1
    "*without it showing up in the object*", "*without the methods being inside the object*" - why don't you want these? What is the actual problem you are facing with the methods being inside the object? – Bergi Oct 10 '22 at 02:25
  • Do you want to put the methods on the prototype of the object maybe? – Bergi Oct 10 '22 at 02:25
  • @Phil Yeah, it's a course assignment problem. I fulfilled most of the requirements of the problem, just not the part where it says method shouldn't be inside the object. Like, I got all of the ouputs needed, except for the fact that the Bird object still has the setColor, addLocations, and getLocations method. – kidnoj Oct 10 '22 at 02:26
  • 1
    @kidnoj Please share (quote) the exact assignment text then, and/or the code that they use to test the requirements. You can [edit] your question to include it. – Bergi Oct 10 '22 at 02:27
  • @Bergi my expected output is an object that contains { species: value, color : value, locations : value} only. My actual output is: {species : value, color : value, locations :value, setColor :function, addLocation : function} I'm trying to figure out on my own how to remove those methods. However, the problem is the prompt for the problem I'm dealing with requires that I create those methods at the end, and have them execute on the object properties, without being in the object. – kidnoj Oct 10 '22 at 02:30
  • @Bergi I'll look up prototype methods and see if that will help, thank you! – kidnoj Oct 10 '22 at 02:31
  • I feel you may be misinterpreting the requirements which makes it even harder for us to understand your question. Please [edit] your post to include the exact instructions you've been given. Do not edit them or paraphrase – Phil Oct 10 '22 at 02:35

2 Answers2

1

I believe you may be interested in an object-oriented style (using the new keyword). Overall using Object.defineProperties can help to prevent methods from appearing under enumeration.

function Bird(species, color, locations) {
  Object.assign(this, {
    species,
    color,
    locations
  });
};
Object.defineProperties(Bird.prototype, {
  getColor:     { enumerable: false, value: function() { return this.color; } },
  setColor:     { enumerable: false, value: function(color) { this.color = color; } },
  addLocation:  { enumerable: false, value: function(loc) { this.locations.push(loc); } },
  getLocations: { enumerable: false, value: function() { return this.locations; } }
});

const bird = new Bird('canary', 'red', ['newyork', 'spain'])

console.log(bird)
console.log(bird.getColor());
bird.setColor('yellow');
console.log(bird.getColor());
bird.addLocation('france');
console.log(bird.getLocations());

Note that you can omit enumerable: false, because if omitted it defaults to false. I only included it to make the behaviour of Object.defineProperties appear more explicit.

Note that this stops the properties from "showing up on the object" in some contexts but not all.

Gershom Maes
  • 7,358
  • 2
  • 35
  • 55
  • 1
    Why [overwrite the `.prototype`](https://stackoverflow.com/questions/17474390/defining-a-javascript-prototype)? Why use an object with a `null` prototype? Just `Object.defineProperties(Bird.prototype, {…});` – Bergi Oct 10 '22 at 03:05
  • @Bergi I suppose it's a matter of opinion but it can help unexpected property collisions. – Gershom Maes Oct 10 '22 at 03:06
0

Oh, figured out what I needed to do. I created a second object that stored the methods I needed. I then passed that object (birdFunc) into the Object.create method and stored that created object in birdObj. They just wanted our class to use Object.create so I just looked up how to use it.

  function Bird(species, color, locations) {
  const birdObj  = Object.create(birdFunc);
  birdObj.species = species;
  birdObj.color = color;
  birdObj.locations = locations;
  return birdObj;
}

const birdFunc = {
  getColor : function() {
    return this.color;
  },
  setColor : function(newColor) {
    this.color = newColor;
  },
  addLocation : function(newLocation) {
    this.locations.push(newLocation);
  },
  getLocations : function() {
    return this.locations;
  }
}
kidnoj
  • 21
  • 2