我正在寻找一种优秀/优雅的方式来验证javascript对象是否具有所需的属性,到目前为止这就是我所拥有的:
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中有更高效/优雅的方法吗?
编辑:好的,所以我很高兴我问,因为我完全错过了一堆可能的条件,比如零。
窗外优雅,验证功能如何?还有其他我应该检查的情况吗?
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");
}
答案 0 :(得分:4)
如果您想要"优雅",您正在寻找的内容称为FirstName = "abcxyz"
:
schema

要解决@AndreFigueiredo's迂腐问题,您还可以检查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).map(function (property) {
var validator = schema[property];
return [property, validator(object[property])];
}).reduce(function (errors, pair) {
if (pair[1] === false) {
errors.push(new Error(pair[0] + " is invalid."));
}
return errors;
}, []);
if (errors.length > 0) {
errors.forEach(function (error) {
console.log(error.message);
});
} else {
console.log("info is valid");
}
}
validate(info, schema);
是否包含该属性:
object

这是一个使用ECMAScript 6版本功能的现代化解决方案,包括destructuring,arrow functions,Object.entries()
,template literals和for...of
:
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])];
}).reduce(function (errors, entry) {
if (!entry[1]) {
errors.push(new Error(entry[0] + " is required."));
} else if (entry[1] && !entry[2]) {
errors.push(new Error(entry[0] + " is invalid."));
}
return errors;
}, []);
if (errors.length > 0) {
errors.forEach(function (error) {
console.log(error.message);
});
} else {
console.log("info is valid");
}
}
validate(info, schema);

执行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
.entries(schema)
.map(([property, validate]) => [
property,
validate(object[property])
])
.reduce((errors, [property, valid]) => {
if (!valid) {
errors.push(new Error(`${property} is invalid.`));
}
return errors;
}, []);
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

答案 1 :(得分:2)
您可以使用 https://github.com/jquense/yup 来解决您的问题。
import * as yup from 'yup';
let schema = yup.object().shape({
name: yup.string().required(),
age: yup.number().required().positive().integer(),
address: yup.string().required(),
});
var info = {
name: "John Doe",
age: "",
phone: "123-456-7890"
}
// check validity
schema
.isValid(info)
.then(function (valid) {
valid; // => false
});
这不仅仅是检查字段是否存在,它还确保数据类型正确,例如那个年龄是一个非负数。
答案 2 :(得分:1)
我认为你应该更关心检查它的正确方法,而不是最优雅。 我将从Todd Moto的一篇非常好的帖子中删除一个链接:Please, take a look
简而言之,您的代码应如下所示:
var array1 = [1,2,3,4,5],
array2 = [1,3,5],
filtered = array1.filter(e => !array2.includes(e));
console.log(filtered);
注意:检查它有值时要小心,javasscript中的许多表达式都是假的(例如.0,false等),但它们都是有效值。
答案 3 :(得分:1)
我会真正检查空字符串,因为0
是假的,但是一个值而不是空的。
function validateFields(object, keys) {
keys.forEach(function (k) {
if (k in object) {
console.log(k + ": " + object[k]);
if (object[k] === '') {
console.log(k + " exists but is empty");
}
return;
}
console.log(k + " doesn't exist in object");
});
}
var fields = ['name', 'age', 'address', 'zeroString', 'zeroNumber'],
info = { name: "John Doe", age: "", phone: "123-456-7890", zeroString: '0', zeroNumber: 0 };
validateFields(info, fields);