javascript 资料型態/结构验证库 : Skeletons
栏目: JavaScript · 发布时间: 5年前
内容简介:当初专案需要将资料以JSON格式储存在本地端,万一资料结构出了问题或是不符合预其,后面程式都会出问题,因此想写一个简单直觉的纯JS资料验证方法,并开源到npm上。希望对大家有帮助。喜欢可以给个星:) 有任何讨论都欢迎。先来介绍一下Javascript有趣的资料型态,如有错误请帮忙提出修正~
当初专案需要将资料以JSON格式储存在本地端,万一资料结构出了问题或是不符合预其,后面程式都会出问题,因此想写一个简单直觉的纯JS资料验证方法,并开源到npm上。
希望对大家有帮助。喜欢可以给个星:) 有任何讨论都欢迎。
源码
Javascript 型态
先来介绍一下Javascript有趣的资料型态,如有错误请帮忙提出修正~
JS 共有七种资料型态
其中包含六种 Primitive types :
- Boolean
- Null
- Undefined
- Number
- String
- Symbol
和 Object
特别的是 Function 广义来说也是属于物件。
我们可以用 typeof
来检查型态 (回传一个字串)
typeof 1 // 'number' typeof "" // 'string' typeof true // 'boolean' typeof undefined // 'undefined' typeof null // 'object' typeof Symbol // 'symbol' typeof function(){ } // 'function' typeof {} // 'object' 复制代码
等等,你有没有发现什麽端倪?我们一个一个看。
Number
一般我们会直接定义变数:
let a = 1 复制代码
也可以用 function 定义
let a = Number(1) typeof a // 'number' 复制代码
但如果加上 new
,则会创建一个Number 物件
let a = new Number(1) typeof a // 'object' 复制代码
NaN
也是属于Number
typeof NaN // 'number' 复制代码
如果要判断变数 a
是可计算的数字且不是 NaN
,以下是行不通的
if(typeof a==='number' && a!==NaN) //... a !== NaN 永远是 true 复制代码
因为 NaN
很特别,它不会等于任何值
// 以下通通都是 false ! NaN == 0 NaN == false NaN == NaN NaN === NaN 复制代码
你可能会想到用 boolean
来判断 true
/ false
if(typeof a==='number' && !a) // ... 复制代码
但是别忘了还有个 0
:
if(typeof a==='number' && !a && a !== 0) // ... 复制代码
当然最简单的是用 isNaN
这个方法区分
if(typeof a==='number' && !isNaN(a)) // ... 复制代码
Boolean, String
和 Number 很像,注意用new的话会一样是创建object。
let a = true // boolean a = Boolean(true) //boolean a = new Boolean(true) //object 复制代码
Undefined
也是一种premitive type
undefined
和 null
是没有 funtion的 ,直接指定值就好
typeof undefined // 'undefined' 复制代码
值得一提的是,虽然以下都是否定值 (false)
Boolean(0) Boolean(false) Boolean('') Boolean(undefined) Boolean(null) 复制代码
但动态型别方面 0, false, ''
是一伙的, undefined, null
则是另外一个团体
0 == false // true 0 == '' // true false == '' // true undefined == null // true undefined == false // false undefined == 0 //false null == '' //false 复制代码
Null
null也是一种type,但是。。。
typeof null // 'object' 复制代码
没错, typeof
打印出来的是 'object'
上网查了一下,有些人说是JS当初设计的错误。
我们要判断一个变数是物件的话可以这样:
if(typeof a === 'object' && a!==null) // ... 复制代码
Symbol
最后一个 premitive type symbol
创建一个 symbol:
let a = Symbol() typeof a // 'symbol' 复制代码
注意不能用 new
,会丢出错误
let a = new Symbol() > Uncaught TypeError: Symbol is not a constructor 复制代码
Object
除了上面六种 primitive type,其他都归类为物件
但特别的是 function
,使用 typeof
检查会回传 function
字串:
typeof function(){} // 'function' 复制代码
让我们能很好的区别 function 和其他一般的物件
Skeletons
接下来要介绍这个库了,有兴趣的话可以先看看 介绍 。
请先记好上面 Javascript 原生定义的资料型别,因为这个库的分类有些不一样
Skeletons 中可定义的类型除了原本的七种JS类型,额外分出 array 和 function
原因是这两个都是很常用的,将他们从物件特别区分出来。
使用方法
定义一个规则,使用 validate
来验证资料
const rule = new Skeletons(schema) rule.validate(data) 复制代码
Schema
定义规则需要传入一个 schema
,也就是你设想的资料结构以及形态
schema 可以有四种
1. premitive type function
共有四种可以用 (undefined和null是没有function的,我们后面谈如何定义)
- Number
- Boolean
- String
- Symbol
分别定义四种形态,使用上不用呼叫,直接传入function
如下,定义一个型态为数字的schema
const schema = Number 复制代码
2. 使用 object literal
使用最值觉的 object literal 来定义一个物件 (注意,在Skeletons会排除array和function)的key
每个key都可指派另一个schema
如下定义了一个有 x, y 两个键的物件,且两个键的值都是数字型态
const schema = { x: Number, y: Number } 复制代码
使用这种方式,让你能够轻易地定义结构较深的物件
const userSchema = { name: String, id: String, VIP: { code: Number, details: { type: String, level: Number, expired: Boolean } }, } 复制代码
3. array literal
使用array literal来定义有固定元素數量的array
const schema = [String, Number, Skeletons.Function()] 复制代码
4.呼叫Skeletons的静态方法
- Skeletons.Number()
- Skeletons.String()
- Skeletons.Boolean()
- Skeletons.Null()
- Skeletons.Symbol()
- Skeletons.Any()
- Skeletons.Array()
- Skeletons.Object()
- Skeletons.Function()
- Skeletons.MapObject()
共有十种方法,分别代表是五种premitive type (不含undefined)、Object, 从物件中分出来的 Array, Function,以及特殊的Any(任何非undefined的型态) 和 MapObject
每种方法都接受一个 options
物件当做参数,
且都可定义三个基本的property
-
options.required
type:
Boolean
default:
true
Skeletons对于任何
undefined
值都会认定为验证失败:new Skeletons({ a: Number }).validate({}) // data.a got undefined, validation filed 复制代码
如果要允许该层资料可以为
undefined
,设options.required
为 falsenew Skeletons({ a: Skeletons.Number({ required: false }) }) 复制代码
-
options.default
type: 任何
default:
undefined
有时后资料的预设值(或者空值)的型态可能会和资料有值的时后不一样,比方说有人可能会用
null
来替代空的物件。new Skeletons(Skeletons.Object({ default: null })) 复制代码
-
options.validator
type:
Function
传入一个function,回传
true
/false
来验证资料validator(value, data) 复制代码
该函数可接收两个参数:
value
代表该层资料的值,data
代表整个资料以下这个例子,
value
等于120
,data
等于整个datasource
const datasource = { a: 120, b: 240 } new Skeletons({ a: Skeletons.Number({ validator: (val, data) => { // in this case, val = 120, data = datasource return val === data.b*2 } }), b: Number }) 复制代码
更多详细的介绍可以参考 文件
验证
验证可分为
- 使用 console 打印出错误资讯
- 直接抛出错误
如何设定可参考 文件
每次验证后,可由 warnings
属性获得错误资讯
const rule = new Skeletons(Number) rule.validate('1') rule.warnings // 一串array 包含所有错误资讯 复制代码
关于错误资讯可参考 warnings
示例
接下来演示一些资料定义的范例
范例一 : 阵列
定义一个 schema
代表不是 NaN
的 number
// ex: 1 const calcNum = Skeletons.Number({ allowNaN: false }) 复制代码
定义一个 array
,每个元素是含有 x
, y
属性,值为非 NaN
数字的物件
// ex: [{x: 1, y: 2}, {x: 3, y: 5}] new Skeletons( Skeletons.Array({ item: { x: calcNum, y: calcNum } }) ) 复制代码
规定 array
一定要有元素
// ex: [{x: 1, y: 2}, {x: 3, y: 5}] new Skeletons( Skeletons.Array({ validator: ary=>ary.length>0, item: { x: calcNum, y: calcNum } }) ) 复制代码
范例二 : 和其他资料比对
假设有一笔资料,当 age
大于 18, grownup
等于 true
代表已成年,反之则为 false
const ex = { age: 19, grownup: true } 复制代码
我们可以用 validator
来进行检查
new Skeletons( { age: Number, grownup: Skeletons.Boolean({ validator: (val, data) => val === data.age>=18 }) } ).validate(ex) 复制代码
范例三: 不限制物件的key
有时后物件作为一个类似map来除存对应的key,代表并没有固定的属性值和数量。这时可以使用 MapObject
例如 room
以房间的id当做key来mapping
const room = { idkfd: { name : 'have fun', members: 4, id: 'idkfd' }, ckclo: { name : 'My room', members: 2, id: 'ckclo' }, ppqkd: { name : 'User0001\'s room', members: 8, id: 'ppqkd' } } 复制代码
可这样定义
new Skeletons( Skeletons.MapObject({ keyValidator: (k, data)=> k === data[k].id, item: { name: String, members: Number, id: String } }) ) 复制代码
以上所述就是小编给大家介绍的《javascript 资料型態/结构验证库 : Skeletons》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 表单正则验证及文件上传验证功能
- angular 实现同步验证器跨字段验证
- Spring Security验证流程剖析及自定义验证方法
- TensorFlow 推出数据验证函数库 TFDV,用于分析和验证
- TensorFlow 推出数据验证函数库 TFDV,用于分析和验证
- 滑动验证码的原理并利用 Vue 实现滑动验证码
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。