Hello. There is some constructor.

var Animal = function (data) { this.name = data.name; this.age = data.age; this.kind = data.kind; } 

It is necessary to validate the input data. That is, make sure that typeof name === String , typeof age === 'number' and 1+['cat', 'dog', 'mongoose'].indexOf(kind) . How to check this is obvious. The question is where to check. Right in the constructor? Or so:

 var validate = function () { if (typeof this.name !== 'string') throw new Error; if (typeof this.age !== 'number') throw new Error; if (-1 === ['cat', 'dog', 'mongoose'].indexOf(kind)) throw new Error; }, Animal = function (data) { this.name = data.name; this.age = data.age; this.kind = data.kind; validate.call(this); } 

How to do it right?

@eicto

the difference in my and your code is also this - I first validate and then initialize

 Animal = function (data) { validate.call(this); this.name = data.name; this.age = data.age; this.kind = data.kind; } 

The fact that the validation takes place in the designer is already considered a sign of gavnokod?

@Etki,

But if you do not strive to write the perfect code right away - well, uh, this is sad.

Well, why would I raise this question at all if I didn’t try to write normal code initially))?

  • one
    Validation should be done before the data gets into the constructor - MasterAlex
  • 2
    @MasterAlex why? Those. Why is this data validation for an object, should some other object deal with? - zb '
  • one
    @alvoro do for example the method Animal.prototype.validate = function (data) {return // object itself or false if the validation fails. } call the method from the constructor, my general opinion is that the object itself should take care of its data, it must be used outside, according to the interface specification. - zb '
  • one
    no, not before the data hits, but before the data gets processed by the constructor, call the validator from the constructor, but it must be the method of the object itself, still (mb even the ray) do this not by the method of the object but by a function in the style Animal Animal = (function ( ) {function validate (data) {} var Animal = function (data) {validate (data);} return Animal;} ()); then you can not shine the validation method out. - zb '
  • one
    @alvoro: Ask yourself the question: why should someone besides the object itself know and be responsible for the data the object can work with? Why should an object trust data verified by someone else? What happens if the views of the verifier and the object itself disagree? How can an object know that the input data has been verified - should it trust anyone who calls the constructor? - VladD

1 answer 1

To write validating code immediately, without thinking, but following certain rules, it is better to use TypeScript or flow . Essentially, your question is: not so important, where to check for the first time, but it’s wise to do the function this.valid() to find out the status of the instance at any time, and this is more useful than throwing exceptions. But if the idea is this:

 var Animal = function (data) { if(data === null || typeof data !== 'object') throw new Error; this.name = data.name; this.age = data.age; this.kind = data.kind; this.validate(); }; Animal.prototype.validate = function () { if (typeof this.name !== 'string') throw new Error; if (typeof this.age !== 'number') throw new Error; if (-1 === ['cat', 'dog', 'mongoose'].indexOf(kind)) throw new Error; }; 
  • one
    I would only call it valid() and not throw the exception in it, but return it boolean, handling the error in a separate loop. - 11111000000
  • In general, it is necessary to validate not the state of this object, but the correctness of the input parameters ( data ). For example, your approach will not work if the constructor expects data.name an object with the properties givenName and familyName . If data forget to set the name field, the constructor will drop on the line this.givenName = data.name.givenName , even before calling vailidate() . - dzhioev
  • In general, yes, indeed, especially if the task is to validate the input parameters, and not the object itself (which, however, I encounter in practice more often), however, you are wrong that the designer will fail in the absence of a name , because this is a completely regular situation. Another thing is to access the property of a non-existent object, and to handle this case, you need to do if(data === null || typeof data !== 'object') threw new Error need a null check, because in js typeof null === 'object' - 11111000000
  • pardon me, I didn’t notice that you mean exactly the name is an object, then everything is correct, but again, it is this fact that must be validated first - 11111000000