1

I have been fiddling around with object building via composition in Javascript (specifically NodeJS) and I have come up with a way of building up my objects but I need to know if this is an insane way of doing things.

The simple version is this: I have two objects, both have two properties, one holding a number and the other holding a string.

File: Cat.js

function Cat() {
  this.name = 'Fuzzy Whiskerkins';
  this.owner = 'James';
}
module.exports = Cat;

File: Car.js

function Car() {
  this.color = 'blue';
  this.owner = 'James';
}
module.exports = Car;

I would like to now add a basic getter/setter function for all properties in both of these objects. I would also like to be able to check that the value passed into these setters matches the type. Instead of writing four prototype functions for each of these properties I have done the following:

File: StringProperty.js

module.exports = function(newObject, propertyName) {
  newObject.prototype[propertyName] = function( newString ) {
    if ( typeof newString !== 'undefined' ) {
      if ( typeof newString !== 'string' ) {
        return;
      }
      this.properties.[propertyName] = newString;
      return this;
    }
    return this.properties.[propertyName];
  }
}

File: Cat.js

var StringProperty = require('./StringProperty.js');
function Cat() {
  this.properties.name = 'Fuzzy Whiskerkins';
  this.properties.owner = 'James';
}
StringProperty( Cat, 'name' );
StringProperty( Cat, 'owner' );
module.exports = Cat;

File: Car.js

var StringProperty = require('./StringProperty.js');
function Car() {
  this.properties.color = 'blue';
  this.properties.owner = 'James';
}
StringProperty( Car, 'color' );
NumberProperty( Car, 'owner' );
module.exports = Car;

Now both objects have all the basic functionality they need and I was able to do it with a minimal amount of code and whenever I need to add another string property the amount of code I will have to add will be minimal.

Am I crazy? Is this an insane thing to/is there a better way to be doing this?

EDIT: What I am trying to accomplish with this is the application I am working on has 100+ objects and each with 10+ properties and the idea of having to write almost the exact same code for every single one of those properties does not set well with me. I would prefer to be able to have a bit of code that adds the property and creates the getter/setter functions (with adding options for divergence in property restrictions such as different length restrictions on string properties). I have looked at multiple examples of object construction via composition in JS but nothing I tried fit into the NodeJS module structure.

  • 2
    What functionality do you need that isn't already available by directly getting or setting the properties? – Mark Nov 08 '17 at 17:22
  • 2
    When you have both a function assigned to the prototype and value assigned directly to the property, the function on the prototype will be "hidden" and will not be normally used at all. I'd strongly suggest you describe the problem you're actually trying to solve so we can direct you better. I would guess that you should be using a getter and setter which are completely supported via [`Object.defineProperty()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty) or `Object.defineProperties()`. – jfriend00 Nov 08 '17 at 17:26
  • @Mark_M I want to run series of tests on the new value before setting it into the object. These tests are essentially the same across all properties and I don't want to have to almost copy and paste the same code over and over. – James Rasmussen Nov 08 '17 at 19:58
  • @jfriend00 Thank you for the referral to Object.defineProperty() or Object.defineProperties(), I think this is what I have been looking for. I will let you know if it works out for me. – James Rasmussen Nov 08 '17 at 20:32

1 Answers1

0

Your solution will not work. You're shadowing the accessor method as soon as you set a value. Also, why are you testing for typeof !== "number" on in a method that expects a string?

Resolving those issues, your type checking just silently exits. You'll hate that once you try to set a value and can't figure out why it's not setting. I'd use TypeScript if you want a stronger type system.

I think you'd be better off trying to write idiomatic JS code. Use the features the language provides in their simplest and most direct manner. Don't try to be too clever with these constructs. Before JS had all its new features, people tried stuff like this, and it never seemed to go that well.

  • The `typeof !== "number"` was a mistake on my part when I was converting my production code into a simple example. As for the shadowing, the code I was testing with was putting the properties into hash `this.properties.propertyName = ' to prevent that overwriting. There was logging in place to print to explain why the new value wasn't set. I will edit my original post to describe what I am looking to do. – James Rasmussen Nov 08 '17 at 20:04