[CodeReview]最优雅的getIndex
缘起
实现一个 getIndex 方法,用于判断某元素在兄弟元素中的排位。
challenge来啦
我的第一个回答
2017 年 09 月 30 日我的实力就是这样的。要认清现实,要坦然面对。
var findIndex = function(target){
var index
[].forEach.call(target.parentNode.children, function(elm, i){
if(elm === target){
index = i
}
})
return index
}
在这个答案之后,故事也就开始了。开始有同学提出了一些代码上的改进建议。觉得不爽是肯定的,人之常情,但这些建议真的很棒。我纷纷采纳了。
ES6 的强大与优雅——初体会
ES7 中新增 spread operator
Spread syntax allows an iterable such as an array expression to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.
代码该进入下:
var findIndex = function(target){
var index
[...target.parentNode.children].forEach(function(elm, i){
if(elm === target){
index = i
}
})
return index
}
回看 ES5 indexOf 的强大
数组获得元素的 index 根本不用遍历之后找到匹配项,直接调用 indexOf 方法即可。
var findIndex = function(target){
return [...target.parentNode.children].indexOf(target)
}
如果这么一说,我第一个实现方式,即使不用 ES6 也可以继续优化,本身就写麻烦了。对比一下代码,原来写了那么多年的循环查找,在这个问题上的写法是这么得愚蠢!
var findIndex = function(target){
return [].slice.call(target.parentNode.children).indexOf(target)
}
于是在这一刻我也明白了,indexOf 不过是一个语法糖而已。
关于 indexOf 兼容性的问题,可以读读这个博客[1]
终极方案
彻底感受 ES6 的简洁与强大!!
let findIndex = (target)=>[...target.parentNode.children].indexOf(target);
【2017-11-18 更新】而实际上,这个终极方案是最优雅的代码,但不是性能最高的代码(因为 indexOf 是语法糖)。而实际上,我们平时写代码,易读性的价值远大于性能,因为易读性带来可维护性。在没有严重性能的影响下,可维护性才是最宝贵的。
尾声
《javascript 高级程序编程》的作者 Nicholas C. Zakas 曾经说过如下内容[2]
A good front end engineer needs to be able to pick things up quickly. The technologies powering the Web aren’t standing still,
时代发展太快了。之前写过的 js 类数组转数组的方法,获得了 4k 的阅读量。而现在再看当时的萌新,也只不过是落后的技术了。现在想来真是有感慨啊🐝