Javascript-检查对象是否具有必需属性的优雅方法 [英] Javascript - elegant way to check object has required properties
问题描述
我正在寻找一种好的/优雅的方法来验证javascript对象是否具有必需的属性,到目前为止,这就是我所拥有的:
I'm looking for an good / elegant way to validate that a javascript object has the required properties, so far this is what I have:
var fields = ['name','age','address'];
var info = {
name: "John Doe",
age: "",
phone: "123-456-7890"
}
var validateFields = function(o, required_fields) {
required_fields.forEach(function(field){
if(o.hasOwnProperty(field)){
if(o[field]){
console.log(field + ": " + o[field]);
}else{
console.log(field + " exists but is empty");
}
}else{
console.log(field + " doesn't exist in object");
}
});
}
validateFields(info, fields);
在普通的javascript中,有没有更有效/更优雅的方法?
Is there a more efficient / elegant way of doing this in plain javascript?
好吧,我很高兴问我,因为我完全错过了很多可能的条件,例如零.
Ok so I'm glad I asked because I had completely missed a bunch of possible conditions like zero.
优雅的窗外,如何验证功能呢?我还有其他情况要检查吗?
With elegance out the window, how is this for a validation function? Are there any other cases I should be checking for?
var fields = ['name','age','address'];
var info = {
name: "John Doe",
age: 0,
address: false,
phone: "123-456-7890"
}
var validateFields = function(o, required_fields, null_valid, zero_valid, empty_valid) {
var invalid_fields = [];
required_fields.forEach(function(field){
if(field in o){
switch(o[field]){
case '':
console.log(field + " exists but is empty");
if(!empty_valid){
invalid_fields.push(o[field]);
}
break;
case undefined:
console.log(field + " exists but is undefined");
invalid_fields.push(o[field]);
break;
case null:
console.log(field + " exists but is null");
if(!null_valid){
invalid_fields.push(o[field]);
}
break;
case 0:
console.log(field + " exists and the value is 0");
if(!zero_valid){
}
invalid_fields.push(o[field]);
break;
default:
console.log(field + ": " + o[field]);
break;
}
}else{
console.log(field + " doesn't exist in object");
invalid_fields.push(o[field]);
}
});
return invalid_fields;
}
var invalid = validateFields(info, fields, true, true, false);
console.log(invalid);
if(invalid.length >0){
console.log("ERROR: Missing fields");
}else{
console.log("Fields are valid");
}
推荐答案
如果您想要优雅",您正在寻找的被称为 schema
:
If you want "elegant", what you're looking for is called a schema
:
var schema = {
name: function (value) {
return /^([A-Z][a-z\-]* )+[A-Z][a-z\-]*( \w+\.?)?$/.test(value);
},
age: function (value) {
return !isNaN(value) && parseInt(value) == value && value >= 18;
},
phone: function (value) {
return /^(\+?\d{1,2}-)?\d{3}-\d{3}-\d{4}$/.test(value);
}
};
var info = {
name: "John Doe",
age: "",
phone: "123-456-7890"
};
function validate(object, schema) {
var errors = Object.keys(schema).filter(function (key) {
return !schema[key](object[key]);
}).map(function (key) {
return new Error(key + " is invalid.");
});
if (errors.length > 0) {
errors.forEach(function (error) {
console.log(error.message);
});
} else {
console.log("info is valid");
}
}
validate(info, schema);
要寻址 @AndreFigueiredo的pedantry,您还可以检查 object
是否完全包含该属性:
To address @AndreFigueiredo's pedantry, you can also check if the object
contains the property at all:
var schema = {
name: function (value) {
return /^([A-Z][a-z\-]* )+[A-Z][a-z\-]*( \w+\.?)?$/.test(value);
},
age: function (value) {
return !isNaN(value) && parseInt(value) == value && value >= 18;
},
phone: function (value) {
return /^(\+?\d{1,2}-)?\d{3}-\d{3}-\d{4}$/.test(value);
}
};
schema.name.required = true;
schema.age.required = true;
var info = {
// name: "John Doe",
age: "",
phone: "123-456-7890"
};
function validate(object, schema) {
var errors = Object.keys(schema).map(function (property) {
var validator = schema[property];
return [property, !validator.required || (property in object), validator(object[property])];
}).filter(function (entry) {
return !entry[1] || !entry[2];
}).map(function (entry) {
if (!entry[1]) return new Error(entry[0] + " is required.");
else return new Error(entry[0] + " is invalid.");
});
if (errors.length > 0) {
errors.forEach(function (error) {
console.log(error.message);
});
} else {
console.log("info is valid");
}
}
validate(info, schema);
这是使用ECMAScript 6版本的功能的现代化解决方案,其中包括 destructuring ,箭头函数, Object.entries()代码>
,模板文字,以及 for ... of
:
Here's a modernized solution using features from ECMAScript 6 edition including destructuring, arrow functions, Object.entries()
, template literals, and for...of
:
const schema = {
name: value => /^([A-Z][a-z\-]* )+[A-Z][a-z\-]*( \w+\.?)?$/.test(value),
age: value => parseInt(value) === Number(value) && value >= 18,
phone: value => /^(\+?\d{1,2}-)?\d{3}-\d{3}-\d{4}$/.test(value)
};
let info = {
name: 'John Doe',
age: '',
phone: '123-456-7890'
};
const validate = (object, schema) => Object
.keys(schema)
.filter(key => !schema[key](object[key]))
.map(key => new Error(`${key} is invalid.`));
const errors = validate(info, schema);
if (errors.length > 0) {
for (const { message } of errors) {
console.log(message);
}
} else {
console.log('info is valid');
}
以及执行 required
和 validate
的版本分别进行检查:
And the version that performs required
and validate
checks separately:
const schema = {
name: value => /^([A-Z][a-z\-]* )+[A-Z][a-z\-]*( \w+\.?)?$/.test(value),
age: value => parseInt(value) === Number(value) && value >= 18,
phone: value => /^(\+?\d{1,2}-)?\d{3}-\d{3}-\d{4}$/.test(value)
};
schema.name.required = true;
schema.age.required = true;
let info = {
// name: 'John Doe',
age: '',
phone: '123-456-7890'
};
const validate = (object, schema) => Object
.entries(schema)
.map(([key, validate]) => [
key,
!validate.required || (key in object),
validate(object[key])
])
.filter(([_, ...tests]) => !tests.every(Boolean))
.map(([key, invalid]) => new Error(`${key} is ${invalid ? 'invalid' : 'required'}.`));
const errors = validate(info, schema);
if (errors.length > 0) {
for (const { message } of errors) {
console.log(message);
}
} else {
console.log('info is valid');
}
这篇关于Javascript-检查对象是否具有必需属性的优雅方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!