如何使用JavaScript判断一个值是否在一个数组中(续)—— JavaScript&TypeScript中的迭代器
本文完整阅读约需 11 分钟,如时间较长请考虑收藏后慢慢阅读~
在『如何使用JavaScript判断一个值是否在一个数组中』一文里,我提到了使用
Array.prototype.includes()
、Array.prototype.indexOf()
两种方法来实现这一需求,但其实对于JavaScript这样一门极为灵活的语言来说,实现方法远不止以上两种。
如标题所示,本文主要提到的就是JavaScript中的迭代器。
0x01
在其他语言(例如Python)中,迭代器是List(Array)甚至Object数据类型中非常重要的一个Feature,可惜JavaScript直到ECMAScript 2015才给予迭代器以正式支持。
0x02
按照文档所示,迭代器的用法见以下代码:
for (each of array) {
console.log(each);
}
即可以通过of
关键词,实现对Array(以及其他可迭代对象,例如 Map
,Set
,String
,TypedArray
等)的迭代。
0x03
然而,正如上文所提到的那样,由于迭代器被引入语法规范的时间如此之短,导致我们在实际应用过程中,因为兼容性的考量很难放心大胆使用这个Feature。
好在微软的TypeScript早有考虑。这门语言是JavaScript的超集,为JavaScript开发引入了静态检查和编译机制,和Sass之于CSS的地位相同,但更强大。TypeScript的官方编译器实现不仅在TypeScript中加入了of
迭代器的支持,而且支持将这一迭代器语法在编译过程中实现向下兼容!
- 这是TypeScript代码:
let someArray = [1, "string", false];
for (let entry of someArray) {
console.log(entry); // 1, "string", false
}
- 这是以ES3和ES5为目标版本编译出的JS代码:
var someArray = [1, "string", false];
for (var _i = 0, someArray_1 = someArray; _i < someArray_1.length; _i++) {
var entry = someArray_1[_i];
console.log(entry); // 1, "string", false
}
- 这是以ES2015为目标版本编译出的JS代码:
let someArray = [1, "string", false];
for (let entry of someArray) {
console.log(entry); // 1, "string", false
}
可以看到,ES2015目标版本和TypeScript实现完全一致,而如果要实现向下兼容,只需针对较低版本进行编译即可,这样可以同时保证开发的便捷性与较好的兼容性。
其实Babel也可以实现相同效果,但Babel专注于兼容,TypeScript专注于扩展语法和编译时的静态分析+警告,在日常使用中,后者更为强大。
小声BB:强大的东西不一定好,好的东西,TypeScript所实现的大量特性(如泛型、接口等)更适用于严谨的软件工业,而非学习、实验、玩耍,各位在学习TypeScript的时候千万不要被那么多的Feature给镇住,学自己需要的即可,其他的尽管等编译器报错的时候再去学习也不迟!
0x04
刚刚说了那么多关于迭代器的知识,那么如何使用迭代器来判断一个值是否在一个数组中呢?相信大家也一定心里有谱了。而对于那些遇到问题亟待解决,大叫着TL;DR点击本文链接的读者,代码如下:
- TypeScript版
let array: Number[] = [1, 2, 3, 4, 5];
// 避免类型检查不通过,对Array接口进行重载,增加inArray()方法
interface Array<T> {
inArray(needle): boolean;
}
// 一行代码解决问题
Array.prototype.inArray = (needle: any): boolean => {for (let i of array) if (i === needle) return true; return false;};
console.log(array.inArray(1)); // true
console.log(array.inArray(12)); // false
- JavaScript版(ES2015 or Higher)
Array.prototype.inArray = (needle: any): boolean => {for (let i of array) if (i === needle) return true; return false;};
console.log(array.inArray(1)); // true
console.log(array.inArray(12)); // false
- JavaScript版(ES3 / 5)
Array.prototype.inArray = function (needle) { for (var _i = 0, _a = array; _i < _a.length; _i++) if (_a[_i] === needle) return true; return false; };
console.log(array.inArray(1)); // true
console.log(array.inArray(12)); // false