昨天看了一篇文章,叫做《如何在 JS 代码中消灭 for 循环》,学习到了新的代码编写思路,在这里记录一下。文章中使用到的方法多为JS中的高阶函数和ES6的一些新特性,理解文章中的每个知识点需要我熟练使用高阶函数并熟悉ES6的新特性。由此这想到,想要把代码写的优雅,简略,必须多了解一些函数。像map,filter这样的方法,可以减少代码量,提升工作效率。所以把一些使用率较高的方法整理在下面。

高阶函数并不是说运行效率很高,而是用法很高级,底层的实现依然是循环机制。

=>(箭头函数)

ES6标准新增了一种新的函数:Arrow Function(箭头函数)。

x => x * x;
//相当于
function (x) {
    return x * x;
}

filter(筛选、过滤函数)

现有数组:

let testArr = [3, 4, 5, 2, 3, undefined, null, 0, '', 'A', 'B', 'C', 3];

过滤掉数组中的number类型数据,代码如下:

let testA = testArr.filter(element => typeof(element) !== 'number');

过滤掉数组中的为假的数据:

let testB = testArr.filter(Boolean);

运行结果:

console.log(testA); 
console.log(testB); 

[ undefined, null, '', 'A', 'B', 'C' ]
[ 3, 4, 5, 2, 3, 'A', 'B', 'C', 3 ]

去除重复元素方法1:

//element每个元素值,index是索引值,self是arr自身
let testC = testArr.filter(function (element, index, self) {
    return self.indexOf(element) === index; 
});

去除重复元素方法2,ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值:

let uniq = arr => [...new Set(arr)];

运行结果:

console.log(testC);
console.log(uniq(testArr));

[ 3, 4, 5, 2, undefined, null, 0, '', 'A', 'B', 'C' ]
[ 3, 4, 5, 2, undefined, null, 0, '', 'A', 'B', 'C' ]

map,forEach(遍历)

有如下数组(这个数组的子元素是引用型数据):

let usersArr = [
   {name: 'tom1', age: 10},
   {name: 'tom2', age: 18},
   {name: 'tom3', age: 20},
   {name: 'tom4', age: 5},
];

给18岁以下的人添加一个isChild属性,并赋值true:

usersArr.map(element => 
    element.age < 18 ? {...element, isChild: element.isChild = true} : element;
);

或者

usersArr.forEach(element => 
    element.age < 18 ? {...element, isChild: element.isChild = true} : element;
);

运行结果:

console.log(usersArr);

[ { name: 'tom1', age: 10, isChild: true },
  { name: 'tom2', age: 18 },
  { name: 'tom3', age: 20 },
  { name: 'tom3', age: 5, isChild: true } ]

注意1:以上的usersArr发生了改变是因为usersArr的子元素为object数据类型,即element有引用关系,修改element就是修改usersArr的子元素本身。如果是常量型的数据呢,如下:

let usersArr2 = [
   'tom1',
   'tom2',
   'tom3',
   'tom4',
];

let copy1 = usersArr2.map(element =>
   element + '_test'
);

let copy2 = usersArr2.forEach(element =>
   element + '_text'
)

console.log(usersArr2);
console.log(copy1);
console.log(copy2);

运行结果:

[ 'tom1', 'tom2', 'tom3', 'tom4' ]
[ 'tom1_test', 'tom2_test', 'tom3_test', 'tom4_test' ]
undefined

可以看到,usersArr2未发生改变,copy1发生改变,copy2为undefined。

注意2:forEach方法不会返回任何数据,map会生成一个新的arr返回。

every,some,find,includes,from(判断每个是否满足某个条件,判断某个是否满足条件,查找,包含,浅拷贝生成一个新数组)

判断是否全是成年人:

console.log(usersArr.every(user => user.age >= 18));

判断是否有未成年人:

console.log(usersArr.some(user => user.age < 18));

找出第一个未成年人:

console.log(usersArr.find(user => user.age < 18));

运行结果:

false
true
{ name: 'tom1', age: 10, isChild: true }

判断是否存在原音字母:

let randomStr = 'alsdjfpuqwerlkjsdfj';
let containsVowel = str => [...str].some(char => ['a', 'e', 'i', 'o', 'u'].includes(char));
console.log(containsVowel(randomStr));

运行结果:

true

字符串转数组,生成新数组,生成100以内的随机数10个:

console.log(Array.from('foo'));
console.log(Array.from([1, 2, 3], x => x + x));
console.log(Array.from({length: 10}, _ => Math.floor(Math.random() * 100)));

运行结果:

[ 'f', 'o', 'o' ]
[ 2, 4, 6 ]
[ 61, 9, 31, 92, 95, 74, 74, 15, 79, 10 ]

sort(排序)

如果对一个数组进行排序,最常用的就是冒泡排序了,但是写起来很麻烦,使用sort方法能很方便的排序,如下数组:

var names = ['Google', 'apple', 'Microsoft'];
names.sort(); 
console.log(names); 
var array1 = [1, 30, 4, 21]; 
array1.sort(); 
console.log(array1);

运行结果:

[ 'Google', 'Microsoft', 'apple' ]
[1, 21, 30, 4]

注意:sort方法默认把所有元素先转换为String再排序,因为字符’2’比字符’4’的ASCII码小,所以21在4前。G和M在小写字母a之前同理。

如果想要得到预想中的排序,则需要让sort方法接收一个比较函数:

names.sort(function (s1, s2) {
    let x1 = s1.toUpperCase();
    let x2 = s2.toUpperCase();
    if (x1 < x2) {
        return -1;
    }
    if (x1 > x2) {
        return 1;
    }
    return 0;
});
array1.sort(function (x, y) {
    if (x < y) {
        return -1;
    }
    if (x > y) {
        return 1;
    }
    return 0;
});

运行结果:

[ 'apple', 'Google', 'Microsoft' ]
[ 1, 4, 21, 30 ]

以上是我觉得在可以替代工作中的一些for循环的使用,Array还有很多其它方法,都很简单,就不在这造轮子了,想要学习的同学点击链接学习

有什么问题可以在下方留言。

性感码农,在线解答。

发表评论

电子邮件地址不会被公开。 必填项已用*标注