JS關於Array的includes()的坑
JQuery的val()搭配includes()導致的血案
JavaScript的includes()
-
想知道Array中有沒有包含某元素,可能會想到indexOf()方法,然而他回傳的是index位置或-1還要判斷有點麻煩,而includes()可以直接返回true或false更直觀一點
-
但是要注意如果是Object組成的Array的話可能會有坑,例如我想找array中有沒有name=‘李四’的元素,乍看是這樣:
let array = [{name: '張三'}, {name: '李四'}, {name: '王五'}];
console.log(array.indexOf({name: '李四'}) !== -1); // false
console.log(array.includes({name: '李四'})); // false
- 實際上比較的是記憶體指向的位置,例如:
let man = {name: '李四'};
let array = [{name: '張三'}, man, {name: '王五'}];
console.log(array.indexOf(man) !== -1); // true
console.log(array.includes(man)); // true
- 真的要查找Object組成的Array中是否有符合某屬性的元素,可以這樣用:
let array = [{name: '張三'}, {name: '李四'}, {name: '王五'}];
array.includes(array.filter(e => e.name === '李四')[0])
- 另外這個indexOf()比較的底層其實是相當於’===’,也就是說包含類型,例如ajax返回的是Object的類型,比較的是String類型的話也會找不到
- 還有NaN也是
const arrNum = ['12',23,45,67,8,9,NaN];
console.log(arrNum.includes(NaN)) // true
console.log(arrNum.indexOf(NaN)); // -1
- 總之includes()更好用
JQuery的val()搭配includes()導致的血案
前情提要,我有一個allObjectList是物件組成的清單(裡面的object有數字的id)
mySelect是一個<select>的html元素,選項是id,可多選的下拉清單(也可以單選)
- 我想在allObjectList中篩選出使用者有選中的id構成一個新的ObjectList,所以就這樣寫
- 用$("#mySelect").val()獲取選中的id,因為select的value用這個方法會拿到string,所以在includes()比較時也把id轉成string來比較
var newObjectList = allObjectList.filter(function(obj) {
return $("#mySelect").val().includes(obj.id.toString());
});
- 乍一看運作起來也沒問題。然而當只有單選且id為兩位數以上就出事了
- 因為.val()這個方法用在select上,當有多選時他會得到array,但是只有單選時卻是得到"單個物件"。例如使用者單選中id=“12”,此時我的方法實際上變成
"12".includes()
- 符合條件的變成"1"、“2”、“12”,我想要的只有"12"但是卻把"1"、“2"也一起得到了
- 坑點就在於.includes()這個方法不只array可以用,string也可以用(就是把string拆成數組)我是真的沒想到
教訓
- 老實一點把.val()獲取到的東西先強制轉成Number Array,就可以杜絕這個隱患
var newObjectList = allObjectList.filter(function(obj) {
return convertToNumberArray($("#mySelect").val()).includes(obj.id);
});
/**
* Convert Array of Strings to Array of Numbers
*/
function convertToNumberArray(input) {
if (Array.isArray(input)) {
var result = input.map(function(item) {
return parseInt(item, 10);
});
return result;
} else {
return Array.of(parseInt(input, 10));
}
}
上次修改於 2022-06-20