javascript开发使用奇淫技巧

[目录]

“+ -”符号的特技

比较大小使用 a - b > 0的方式更好,用a > b有时候会出现错误

If,for…in,for…of和的使用

if多条件判断

switch语句优化

字符串拼接:join()

链式取值a[0].b不存在的undefined 问题

  1. 类型强制转换

1.1 string强制转换为数字

1.2 使用filter过滤数组中的所有假值

1.4 双位运算符 ~~实现向下取整

1.5 短路运算符&&、||

1.6 取整 | 0

1.7 判断奇偶数 & 1

  1. 函数

2.1 函数默认值

2.2 强制参数,缺失报错

2.3 箭头函数隐式返回值

2.4 惰性载入函数

2.5 一次性函数

  1. 字符串

3.1 字符串比较时间先后(时间形式注意补0)

  1. 数字

4.1 不同进制表示法

4.2 精确到指定位数的小数

4.3 数字补0操作

  1. 数组

5.1 reduce方法同时实现map和filter

5.2 统计数组中相同项的个数

5.3 交换参数数值

5.4 批量接收多个请求返回结果

5.5 将数组平铺到指定深度

5.6 数组的对象解构

5.7 对象数组按照某个属性查询最大值 是不是比for循环方便了很多。

  1. 对象

6.1 使用解构删除不必要属性

6.2 在函数参数中解构嵌套对象

  1. 代码复用

7.1 Object [key]

Object [key] 实现表单验证

----------------------------正文-----------------------------

#“+ -”符号的特技

用+可以将数值型的字符串转为数字,但是必须结合 isNaN(), isNaN() 函数用于检查其参数是否是非数字,不是数字则为true

基础知识
let a = "2" ,b= '20',c=34 ,d='2'
a-b = -18
c-d = 32
a+b = "220"
a+c = "234"

isNaN('ad') // true
isNaN('22') // false

骚操作
+('ab') // NaN
+('22') // 22
+(22) // 22

let a = 1 , b ='2'
let c = a + +(b) //3

示例
// 选择最小值的函数如下(源于《vuejs权威指南》里看到表单验证validator.js源码)
export default min (val, areg){
    return !isNaN(val) && !isNaN(areg) && +(val)>= +(areg)
}
复制代码

###比较大小使用 a - b > 0的方式更好,用a > b有时候会出现错误

错误结果
'20' > '100' // true
预期结果
'20' - '100' > 0 // false

//数组排序算法
arr.sort((a, b ) =>{
   return a-b 
})
复制代码

#If,for…in,for…of和的使用

1.能用三元运算符就用,减少if的嵌套

2.减少多余条件判断,查询结束立即返回(早返回,多返回),如果是函数返回if里面和外面返回相同的数据类型

3.If…else if…else多个条件时以else结尾,因为符合防御性编程规则

4.NaN不应该用于比较,应该是判断是否是数字

5.Switch…case使用在至少有三个判断值,case不可省,每次case必须用break跳出

6.for…of遍历数组和字符串

可以使用break,return(一个循环一个),continue不使用,降低代码可读性

7.for…in遍历对象

For…in遍历对象包括所有继承的属性,所以如果只是想使用对象本身的属性需要做一个判断

8.在循环内部声明函数慎用,因为是循环执行完成函数调用才会执行

9.Return后面不要写代码

#if多条件判断

“早点返回,经常返回“(return early,return often),If语句用来处理主路径上的异常 比如我们在之前文章中提过的find 函数。


function find(predicate, arr) {
    for (let item of arr) {
        if (predicate(item)) {
            return item;
        }
    }
}

复制代码

在这个find函数内,一旦我们找到想查找的对象就立刻返回该对象并且退出循环。这使得我们的代码更加高效。

也可以结合三元运算符实现高效简洁的代码实现

#switch语句优化

低级版:太容易忘记写break

let notificationPtrn;
switch (notification.type) {
    case 'citation':
        notificationPtrn = 'You received a citation from {{actingUser}}.';
        break;
    case 'follow':
        notificationPtrn = '{{actingUser}} started following your work';
        break;
    case 'mention':
        notificationPtrn = '{{actingUser}} mentioned you in a post.';
        break;
    default:
        // Well, this should never happen
}
复制代码

优化一: 用return

function getnotificationPtrn(n) {
        switch (n.type) {
            case 'citation':
                return 'You received a citation from {{actingUser}}.';
            case 'follow':
                return '{{actingUser}} started following your work';
            case 'mention':
                return '{{actingUser}} mentioned you in a post.';
            default:
                throw new Error('You’ve received some sort of notification we don’t know about.';
        }
    }

    let notificationPtrn = getNotificationPtrn(notification);
复制代码

优化二:采用对象字典

function getNotificationPtrn(n) {
    const textOptions = {
        citation: 'You received a citation from {{actingUser}}.',
        follow: '{{actingUser}} started following your work',
        mention: '{{actingUser}} mentioned you in a post.',
    }
    return textOptions[n.type];
}
复制代码

优化三(推荐) 类似模式匹配方法

const textOptions = {
    citation: 'You received a citation from {{actingUser}}.',
    follow: '{{actingUser}} started following your work',
    mention: '{{actingUser}} mentioned you in a post.',
}

function getNotificationPtrn(textOptions, n) {
    return textOptions[n.type];
}

const notificationPtrn = getNotificationPtrn(textOptions, notification);
复制代码

若包含未知处理,我们也可以把默认的信息作为参数

constdefaultTxt= 'You’ve received some sort of notification we don’t know about.';   // 默认值
function getNotificationPtrn(defaultTxt, txtOptions, n) {
    return txtOptions[n.type] || defaultTxt;
}
const notificationPtrn = getNotificationPtrn(defaultTxt, txtOptions, notification.type);
复制代码

现在textOptions是一个变量,并且该变量不用再被硬编码了。我们可以把它移动到一个JSON配置文件中,或者从服务器获取该变量。现在我们想怎么改textOptions就怎么改。我们可以增加新的选项,或者移除选项。我们也可以把多个地方不同的选项合并到一起。

#字符串拼接:join()

应使用数组保存字符串片段,使用时调用join方法。避免使用+或+=的方式拼接较长的字符串,每个字符串都会使用一个小的内存片段,过多的内存片段会影响性能

#链式取值a[0].b不存在的undefined 问题

开发中,链式取值是非常正常的操作,如:

res.data.goods.list[0].price

但是对于这种操作报出类似于Uncaught TypeError: Cannot read property 'goods' of undefined 这种错误也是再正常不过了,如果说是res数据是自己定义,那么可控性会大一些,但是如果这些数据来自于不同端(如前后端),那么这种数据对于我们来说我们都是不可控的,因此为了保证程序能够正常运行下去,我们需要对此校验:


if (res.data.goods.list[0] && res.data.goods.list[0].price) {

// your code

}

如果再精细一点,对于所有都进行校验的话,就会像这样:

if (res && res.data && res.data.goods && res.data.goods.list && res.data.goods.list[0] && res.data.goods.list[0].price){

    // your code

}

复制代码

不敢想象,如果数据的层级再深一点会怎样,这种实现实在是非常不优雅,那么如果优雅地来实现链式取值呢?

方法一.通过函数解析字符串(lodash的 _.get 方法)

我们可以通过函数解析字符串来解决这个问题,这种实现就是lodash的 _.get 方法(www.lodashjs.com/docs/4.17.5…)


// _.get(object, path, [defaultValue])

var object = { a: [{ b: { c: 3 } }] };

var result = _.get(object, 'a[0].b.c', 1);

console.log(result);

// output: 3

该方法源码实现起来也非常简单,只是简单的字符串解析而已:

function get (obj, props, def) {

    if((obj == null) || obj == null || typeof props !== 'string') return def;

    const temp = props.split('.');

    const fieldArr = [].concat(temp);

    temp.forEach((e, i) => {

        if(/^(\w+)\[(\w+)\]$/.test(e)) {

            const matchs = e.match(/^(\w+)\[(\w+)\]$/);

            const field1 = matchs[1];

            const field2 = matchs[2];

            const index = fieldArr.indexOf(e);

            fieldArr.splice(index, 1, field1, field2);

        }

    })

    return fieldArr.reduce((pre, cur) => {

        const target = pre[cur] || def;

        if(target instanceof Array) {

            return [].concat(target);

        }

        if(target instanceof Object) {

            return Object.assign({}, target)

        }

        return target;

    }, obj)

}


// 使用

var c = {

     a: {

          b : [1,2,3] 

     }

}

_get(c ,'a.b') // [1,2,3]

_get(c, 'a.b[1]') // 2

_get(c, 'a.d', 12) // 12

复制代码

方法二,使用解构赋值

这个思路是来自github上 You-Dont-Need-Lodash-Underscore 这个仓库,看到这个的时候真的佩服

缺点是:可读性不太好


const obj = {

    a:{

        b: [1,2,3,4]

    },

    a1: 121,

    a2: 'name'

}



let {a: result} = obj // result : {b: [1,2,3,4]}

let {a1: result} = obj // result: 121

let {b: result} = obj // result: undefined



当然,这个时候为了保证不报undefined,我们仍然需要定义默认值, 

let {b: result = 'default'} = obj // result: 'default'

复制代码

方法三,使用Proxy

function pointer(obj, path = []) {
    return new Proxy(() => {}, {
        get (target, property) {
            return pointer(obj, path.concat(property))
        },
        apply (target, self, args) {
            let val = obj;
            let parent;
            for(let i = 0; i < path.length; i++) {
                if(val === null || val === undefined) break;
                parent = val;
                val = val[path[i]]    
            }
            if(val === null || val === undefined) {
                val = args[0]
            }
            return val;
        }
    })
}
​
​
使用方法:
var c = {
    a: {
        b : [1,2,3] 
    }
}
​
pointer(c).a();   // {b: [1,2,3]}
pointer(c).a.b(); // [1,2,3]
pointer(d).a.b.d('default value');  // default value
复制代码

问题:为啥new Proxy()第一个参数要是一个箭头函数,我看大部分都是一个对象

解析:Proxy工作的原理,如果是对象的话,下面的apply函数内的内容是不会执行到的 因为proxy要代理函数执行的行为才会去执行apply里面的函数,所以必须要传一个箭头函数

#1. 类型强制转换

##1.1 string强制转换为数字

可以用*1(乘以1)来转化为数字(实际上是调用.valueOf方法) 然后使用Number.isNaN来判断是否为NaN,或者使用 a !== a 来判断是否为NaN,因为 NaN !== NaN


'32' * 1            // 32
'ds' * 1            // NaN
null * 1            // 0
undefined * 1    // NaN
1  * { valueOf: ()=>'3' }        // 3
复制代码

常用: 也可以使用+来转化字符串为数字


+ '123'            // 123
+ 'ds'               // NaN
+ ''                    // 0
+ null              // 0
+ undefined    // NaN
+ { valueOf: ()=>'3' }    // 3
复制代码

##1.2 使用filter过滤数组中的所有假值

我们知道JS中有一些假值:false,null,0,"",undefined,NaN,怎样把数组中的假值快速过滤呢,可以使用Boolean构造函数来进行一次转换


const compact = arr => arr.filter(Boolean)
compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34])             // [ 1, 2, 3, 'a', 's', 34 ]
复制代码

##1.4 双位运算符 ~~实现向下取整

可以使用双位操作符来替代 Math.floor( )。双否定位操作符的优势在于它执行相同的操作运行速度更快。

math.floor(x)返回小于参数x的最大整数,即对浮点数向下取整


Math.floor(4.9) === 4      //true
// 简写为:
~~4.9 === 4      //true
复制代码

不过要注意,对负数来说 ~~ 运算结果与 Math.floor( ) 运算结果不相同:

~~4.5            // 4
Math.floor(4.5)        // 4
~~-4.5        // -4
Math.floor(-4.5)        // -5
复制代码

##1.5 短路运算符&&、||

我们知道逻辑与&&与逻辑或||是短路运算符,短路运算符就是从左到右的运算中前者满足要求,就不再执行后者了; 可以理解为:

&&为取假运算,从左到右依次判断,如果遇到一个假值,就返回假值,以后不再执行,否则返回最后一个真值 ||为取真运算,从左到右依次判断,如果遇到一个真值,就返回真值,以后不再执行,否则返回最后一个假值

let param1 = expr1 && expr2
let param2 = expr1 || expr2
复制代码

&& :expr1&&expr2 如果expr1 能转换成false则返回expr1,否则返回expr2. 因此, 在Boolean环境中使用时, 两个操作结果都为true时返回true,否则返回false.

|| :expr1||expr2 如果expr1能转换成true则返回expr1,否则返回expr2. 因此,在boolean环境(在if的条件判断中)中使用时,二者操作结果中只要有一个为true,返回true;二者操作结果都为false时返回false.

! :!expr 如果单个表达式能转换为true的话返回false,否则返回true. 因此可以用来做很多有意思的事,比如给变量赋初值:


let variable1
let variable2 = variable1  || 'foo'
复制代码

如果variable1是真值就直接返回了,后面短路就不会被返回了,如果为假值,则会返回后面的foo。

也可以用来进行简单的判断,取代冗长的if语句:


let variable = param && param.prop
复制代码

如果param如果为真值则返回param.prop属性,否则返回param这个假值,这样在某些地方防止param为undefined的时候还取其属性造成报错。

但是要注意以下反例如果在数据为0(或者空字符串的时候也要返回数据),此时用||运算符就会搞错了,返回的是默认值了:


// 返回值为

let res = {

     data: 0,     // 后台返回状态码(0表示不存在,1表示存在)

     code: 200

}

let val = res.data || '无数据'

console.log(val)       // '无数据',其实我们要的是data的值

复制代码

##1.6 取整 | 0

对一个数字| 0可以取整,负数也同样适用,num | 0


1.3 | 0         // 1
-1.9 | 0        // -1
复制代码

##1.7 判断奇偶数 & 1

对一个数字& 1可以判断奇偶数,负数也同样适用,num & 1


const num=3;
!!(num & 1)                    // true
!!(num % 2)                    // true
复制代码

#2. 函数

##2.1 函数默认值

func = (x, m = 3, n = 4 ) => (x * m * n);
func(2)             //output: 24
func(null)             //output: 12   因为1*null = 0

复制代码

注意,传入参数为undefined或者不传入的时候会使用默认参数,

但是传入null还是会覆盖默认参数

##2.2 强制参数,缺失报错

默认情况下,如果不向函数参数传值,那么JS 会将函数参数设置为undefined。其它一些语言则会发出警告或错误。要执行参数分配,可以使用if语句抛出未定义的错误,或者可以利用强制参数。

logError = ( ) => {
  throw new Error('Missing parameter!');
}
foo = (bar = logError( ) ) => {     // 这里如果不传入参数,就会执行logError 函数报出错误(此处也可以添加日志打印等操作)
  return bar;
}
复制代码

##2.3 箭头函数隐式返回值

返回值是我们通常用来返回函数最终结果的关键字。只有一个语句的箭头函数,可以隐式返回结果(函数必须省略大括号{ },以便省略返回关键字)。

要返回多行语句(例如对象文本),需要使用( )而不是{ }来包裹函数体。这样可以确保代码以单个语句的形式进行求值。


function calcCircumference(diameter) {
  return Math.PI * diameter
}
// 简写为:
calcCircumference = diameter => (
  Math.PI * diameter;
)
复制代码

##2.4 惰性载入函数

在某个场景下我们的函数中有判断语句,这个判断依据在整个项目运行期间一般不会变化,所以判断分支在整个项目运行期间只会运行某个特定分支,那么就可以考虑惰性载入函数


// 低级版

function foo(){
    if(a !== b){
        console.log('aaa')
    }else{
        console.log('bbb')
    }
}
 
// 优化后
function foo(){
    if(a != b){
        foo = function(){
            console.log('aaa')
        }
    }else{
        foo = function(){
            console.log('bbb')
        }
    }
    return foo();
}
复制代码

那么第一次运行之后就会覆写这个方法,下一次再运行的时候就不会执行判断了。当然现在只有一个判断,如果判断很多,分支比较复杂,那么节约的资源还是可观的。

##2.5 一次性函数

跟上面的惰性载入函数同理,可以在函数体里覆写当前函数,那么可以创建一个一次性的函数,重新赋值之前的代码相当于只运行了一次,适用于运行一些只需要执行一次的初始化代码


var sca = function() {
    console.log('msg')
    sca = function() {
        console.log('foo')
    }
}
sca()        // msg
sca()        // foo
sca()        // foo
复制代码

#3. 字符串

##3.1 字符串比较时间先后(时间形式注意补0)

比较时间先后顺序可以使用字符串:


var a = "2014-08-08";
var b = "2014-09-09";
 
console.log(a>b, a<b); // false true
console.log("21:00"<"09:10");  // false
console.log("21:00"<"9:10");   // true   时间形式注意补0
复制代码

因为字符串比较大小是按照字符串从左到右每个字符的charCode来的,但所以特别要注意时间形式注意补0

附送一个时间格式处理函数


export default{
    // 将时间格式处理为两位数,例如1时1分输出01:01
    twoNumFormat(num){
        return (num < 10)? '0'+ num: num
    },
    // 时间格式化,输出2018-01-02 01:10
    dateFormat: function(date = new Date()){
        let now = new Date(date)
        let year = now.getFullYear()
        let month = (now.getMonth()+1)
        month = this.twoNumFormat(month)
        let day = now.getDate()
        day = this.twoNumFormat(day)
        let hour = now.getHours()
        hour = this.twoNumFormat(hour)
        let minus = now.getMinutes()
        minus = this.twoNumFormat(minus)
        let second = now.getSeconds()
       second = this.twoNumFormat(second )

        return `${year}-${month}-${day} ${hour}:${minus}:${second }`
    }
}
复制代码

#4. 数字

##4.1 不同进制表示法

ES6中新增了不同进制的书写格式,在后台传参的时候要注意这一点。


29            // 10进制
035            // 8进制29      原来的方式
0o35            // 8进制29      ES6的方式
0x1d            // 16进制29
0b11101            // 2进制29
复制代码

##4.2 精确到指定位数的小数

将数字四舍五入到指定的小数位数。使用 Math.round() 和模板字面量将数字四舍五入为指定的小数位数。 省略第二个参数 decimals ,数字将被四舍五入到一个整数。

const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`)
round(1.345, 2)                 // 1.35   Number(1.345e2e-2)
round(1.345, 1)                 // 1.3

// 此处e2表示乘以10的2次方 
1.23e1   //12.3
1.23e2   // 123
123.45e-2  // 1.2345
复制代码

##4.3 数字补0操作

感谢网友 @JserWang @vczhan 提供 这个小技巧 有时候比如显示时间的时候有时候会需要把一位数字显示成两位,这时候就需要补0操作,可以使用slice和string的padStart方法


const addZero1 = (num, len = 2) => (`0${num}`).slice(-len)    // 从字符串倒数第len处开始截取到最后
const addZero2 = (num, len = 2) => (`${num}`).padStart( len   , '0')   // padStart为ES6的字符串拼接方法
addZero1(3) // 03
 
addZero2(32,4)  // 0032
复制代码

此处可以采用另外一个思路;可以将得到的字符串先拼接len个0,然后再截取len长的字符串 #5. 数组

##5.1 reduce方法同时实现map和filter

假设现在有一个数列,你希望更新它的每一项(map的功能)然后筛选出一部分(filter的功能)。如果是先使用map然后filter的话,你需要遍历这个数组两次。 在下面的代码中,我们将数列中的值翻倍,然后挑选出那些大于50的数。


const numbers = [10, 20, 30, 40];
const doubledOver50 = numbers.reduce((finalList, num) => {
  num = num * 2;
  if (num > 50) {
    finalList.push(num);
  }
  return finalList;
}, []);
doubledOver50;            // [60, 80]
复制代码

##5.2 统计数组中相同项的个数

很多时候,你希望统计数组中重复出现项的个数然后用一个对象表示。那么你可以使用reduce方法处理这个数组。

下面的代码将统计每一种车的数目然后把总数用一个对象表示。


var cars = ['BMW','Benz', 'Benz', 'Tesla', 'BMW', 'Toyota'];
var carsObj = cars.reduce(function (obj, name) {
  obj[name] = obj[name] ? ++obj[name] : 1;    // obj[name]存在就加一,不存在就为1
  return obj;
}, {});
carsObj; // => { BMW: 2, Benz: 2, Tesla: 1, Toyota: 1 }
复制代码

##5.3 交换参数数值

有时候你会将函数返回的多个值放在一个数组里。我们可以使用数组解构来获取其中每一个值。


let param1 = 1;
let param2 = 2;
[param1, param2] = [param2, param1];
console.log(param1) // 2
console.log(param2) // 1

当然我们关于交换数值有不少其他办法:

var temp = a; a = b; b = temp            
b = [a, a = b][0]                     
a = a + b; b = a - b; a = a - b        
复制代码

##5.4 批量接收多个请求返回结果

在下面的代码中,我们从/post中获取一个帖子,然后在/comments中获取相关评论。由于我们使用的是async/await,函数把返回值放在一个数组中。而我们使用数组解构后就可以把返回值直接赋给相应的变量。


async function getFullPost(){
  return await Promise.all([
     fetch('/post'),
     fetch('/comments')
  ]);
}
const [post, comments] = getFullPost();
复制代码

##5.5 将数组平铺到指定深度

使用递归,为每个深度级别 depth 递减 1 。

使用 Array.reduce() 和 Array.concat() 来合并元素或数组。 基本情况下,depth 等于 1 停止递归。 省略第二个参数,depth 只能平铺到 1 (单层平铺) 的深度。


const flatten = (arr, depth = 1) =>
  depth != 1
    ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v, depth - 1) : v), [])
    : arr.reduce((a, v) => a.concat(v), []);
flatten([1, [2], 3, 4]);                             // [1, 2, 3, 4]
flatten([1, [2, [3, [4, 5], 6], 7], 8], 2);           // [1, 2, 3, [4, 5], 6, 7, 8]
复制代码

##5.6 数组的对象解构

数组也可以对象解构,可以方便的获取数组的第n个值


const csvFileLine = '1997,John Doe,US,john@doe.com,New York';
const { 2: country, 4: state } = csvFileLine.split(',');
 
country            // US
state            // New Yourk
复制代码

##5.7 对象数组按照某个属性查询最大值

var array=[
        {
            "index_id": 119,
            "area_id": "18335623",
            "name": "满意度",
            "value": "100"
        },
        {
            "index_id": 119,
            "area_id": "18335624",
            "name": "满意度",
            "value": "20"
        },
        {
            "index_id": 119,
            "area_id": "18335625",
            "name": "满意度",
            "value": "80"
        }];
复制代码

一行代码搞定 Math.max.apply(Math, array.map(function(o) {return o.value})) 执行以上一行代码可返还所要查询的array数组中对象value属性的最大值100。

同理,要查找最小值如下即可: Math.min.apply(Math, array.map(function(o) {return o.value})) 是不是比for循环方便了很多。

作者:遇见小美好 来源:CSDN 原文:blog.csdn.net/qq_37268201…

#6. 对象

##6.1 使用解构删除不必要属性

有时候你不希望保留某些对象属性,也许是因为它们包含敏感信息或仅仅是太大了(just too big)。你可能会枚举整个对象然后删除它们,但实际上只需要简单的将这些无用属性赋值给变量,然后把想要保留的有用部分作为剩余参数就可以了。

下面的代码里,我们希望删除_internal和tooBig参数。我们可以把它们赋值给internal和tooBig变量,然后在cleanObject中存储剩下的属性以备后用。


let {_internal, tooBig, ...cleanObject} = {el1: '1', _internal:"secret", tooBig:{}, el2: '2', el3: '3'};
 
console.log(cleanObject);    // {el1: '1', el2: '2', el3: '3'}
复制代码

##6.2 在函数参数中解构嵌套对象

在下面的代码中,engine是对象car中嵌套的一个对象。如果我们对engine的vin属性感兴趣,使用解构赋值可以很轻松地得到它。


var car = {
  model: 'bmw 2018',
  engine: {
    v6: true,
    turbo: true,
    vin: 12345
  }
}
const modelAndVIN = ({model, engine: {vin}}) => {
  console.log(`model: ${model} vin: ${vin}`);
}
modelAndVIN(car); // => model: bmw 2018  vin: 12345
复制代码

#7. 代码复用

##7.1 Object [key]

虽然将 foo.bar 写成 foo ['bar'] 是一种常见的做法,但是这种做法构成了编写可重用代码的基础。许多框架使用了这种方法,比如element的表单验证。

请考虑下面这个验证函数的简化示例:


function validate(values) {
  if(!values.first)
    return false;
  if(!values.last)
    return false;
  return true;
}
console.log(validate({first:'Bruce',last:'Wayne'})); // true
复制代码

上面的函数完美的完成验证工作。但是当有很多表单,则需要应用验证,此时会有不同的字段和规则。如果可以构建一个在运行时配置的通用验证函数,会是一个好选择。

###Object [key] 实现表单验证


// object validation rules
const schema = {
  first: {
    required:true
  },
  last: {
    required:true
  }
}
 
// universal validation function
const validate = (schema, values) => {
  for(field in schema) {
    if(schema[field].required) {
      if(!values[field]) {
        return false;
      }
    }
  }
  return true;
}
console.log(validate(schema, {first:'Bruce'})); // false
console.log(validate(schema, {first:'Bruce',last:'Wayne'})); // true
复制代码
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值