0

Let's say I have the following constructor function

function Planet(solarSystem,habitable) {

    this.solarSystem = solarSystem;
    this.habitable = habitable;

}

And I want to create an instance of this constructor function but I put the wrong parameters type (e.g. because I had 4 beers and I felt like programming):

let earth = new Planet(23, 'wooow');

Question: How can I condition the creation of the instance so that if parameter types are respected --> instance created, otherwise don't assign anything to earth

EDIT: I forgot to specify that I am expecting a Planet(String, boolean) parameters type

9
  • 1
    JS in-built thing for such validations is Proxy object: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented May 13, 2017 at 10:12
  • 1
    You can throw an exception! It is not possible to return undefined from a constructor function. You would have to wrap it then in another creator function that returns a new Planet or undefined/null depending on the parameters. Commented May 13, 2017 at 10:17
  • @wostex No, proxies help absolutely nothing here Commented May 13, 2017 at 11:22
  • How am I supposed to know what parameter types to respect? Commented May 13, 2017 at 11:24
  • 1
    If you want type checking, then use a language such as TypeScript which provides it. In your example, how are you going to continue running your program if earth is not set to anything? Commented May 13, 2017 at 11:27

2 Answers 2

1

There are some solutions to do it:

  • return an object without any property

    function Planet(solarSystem,habitable) {
        if (typeof solarSystem != 'string' && typeof habitable != 'boolean') {
           return Object.create(null);
        }
        this.solarSystem = solarSystem;
        this.habitable = habitable;
    }
    
    var planetObj1 = new Planet('TEST', true);
    console.log('planetObj1 ' , planetObj1 , 'is instanceof Planet', planetObj1 instanceof Planet);
    var planetObj2 = new Planet(14, 'TEST');
    console.log('planetObj2 ', planetObj2, 'is instanceof Planet', planetObj2  instanceof Planet);

  • if you want to return any others JavaScript type such as undefined, null. You can create a prototype to handle it

You can create a prototype to decide to create your new Obj or not

function Planet(solarSystem,habitable) {

        this.solarSystem = solarSystem;
        this.habitable = habitable;

    }

    Planet.CreatePlanet = function(solarSystem, habitable) { 
        if (typeof solarSystem != 'string' && typeof habitable != 'boolean') return null;
        return new Planet(solarSystem, habitable);
    }

    // then instead of new Planet():
    var obj = Planet.CreatePlanet(14, 'habitable');//return null
    console.log(obj);

Sign up to request clarification or add additional context in comments.

Comments

0

You can use a Proxy object to intercept an existing constructor and apply your validation logic:

function Planet(solarSystem,habitable) {
    this.solarSystem = solarSystem;
    this.habitable = habitable;
}

const validate = { // handler for Proxy
  construct: function(target, args) {
    let solarSystem, habitable;
    if (Array.isArray(args) && args.length === 2) {
      solarSystem = (typeof args[0] === 'string') ? args[0] : null;
      habitable = (typeof args[1] === 'boolean') ? args[1] : null;
      return ( solarSystem !== null && habitable !== null)
      	? { solarSystem, habitable} 
        : {}
    } else {
    	return {} // return an empty object in case of bad arguments
    }
  }
}

// new constructor, use it to create new planets
const validPlanet = new Proxy(Planet, validate); 
// usage: const a = new validPlanet(<string>, <boolean>)

// let's use initial buggy constructor:

const earth = new Planet('solar', true);
console.log('earth (Planet): ', earth);

const wrong = new Planet('solar', 15); // this uses the initial constructor, wrong value passes
console.log('wrong (Planet): ', wrong);

// now let's use proxied constrictor with validation

const pluto = new validPlanet('solar', false);
console.log('pluto (validPlanet): ', pluto);

const bad = new validPlanet('solar', 'hello');
console.log('bad (validPlanet): ', bad); // returns an empty object

It's impossible to return 'undefined' here if you provide wrong inputs, because Proxy.construct must return an object. If an empty object is ok, then this should work for you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.