弱类型的Javascript
Javascript是一门弱类型的语言,定义变量不需要指定类型,可以为同一个变量赋任意类型的值。误用类型不会报错,而结果会让你大吃一惊:
> "1" + 1 '11' > if ("false") { console.log("yes") } else { console.log("no"); } yes undefined >
redis中很多数据结构取出时都是字符串值(如:set、hash),调用方需要自行将它转换成正确的类型(如:Boolean、Date、Number),如果不转换成正确的类型会导致冗长的代码,如Boolean类型:
if ((String(model.stoped) == 'true')) { // Do something when stoped. }
如果手工转换成正确的类型肯定要写很多样板代码了。
对象模式验证模块 joi
有很多的ORM( Object Relational Mapping 对象关系映射)库都能够实现强类型的数据模型,但是它们都相当的复杂,支持各种各样的数据库后端,支持一对一、一对多、多对多等数据关系,但是很少支持分表分库,我们的系统一般是数据模型简单但要考虑用户量大了横向扩展,所以一开始就进行了分表分库,无法使用重型的ORM。
如果有一个能够自动根据模式(Schema)定义对值进行类型转换的库,一定会非常有用。
joi 一个Javascript对象模式描述语言以及验证(Object schema description language and validator for JavaScript objects)的库,它可以完成对象类型转换以及合法性验证。
joi 的用法示例
var joi = require('joi'); var redis = require('redis'); var client = redis.createClient(6379, '127.0.0.1'); var User = function (options) { if (! options) { options = {}; } this.id = options.id || 0; this.name = options.name || ''; this.male = options.male || true; this.birthday = options.birthday; }; User.schema = joi.object().keys({ id: joi.number().integer().min(1), name: joi.string().required(), male: joi.boolean().default(true), birthday: joi.date().required() }); User.find = function (id, callback) { client.hgetall("user:" + id, function (err, value) { if (err) { return callback(err); } else if (! value) { return callback(new Error("User not found")); } joi.validate(value, User.schema, callback); }); }; User.prototype.save = function (callback) { var value = {}; for(var fieldName in this) { if (typeof(this[fieldName]) != 'function') { value[fieldName] = this[fieldName]; } } joi.validate(value, User.schema, function (err, validatedValue) { if (err) { return callback(err); } client.hmset("user:" + validatedValue.id, validatedValue, callback); }); }; var user = new User({ id: 1, name: "txf", male: true, birthday: new Date("1983-03-22") }); user.save(function (err) { if (err) { console.error("user save error(" + err.toString() + ")"); client.quit(); return; } console.info("user saved"); User.find(user.id, function (err, user) { client.quit(); if (err) { console.error("user find error(" + err.toString() + ")"); return; } console.log("user found: " + JSON.stringify(user)); }); });
运行结果:
user saved user found: {"id":1,"name":"txf","male":true,"birthday":"1983-03-22T00:00:00.000Z"}