Skip to content

2026-06-08

/ 13 分鐘閱讀

/ Deep JavaScript Foundations v3

相等性練習:實作受控制的強制相等搜尋函式

本文是相等性章節的實作練習。前幾篇完整分析了 == 演算法、各種角落案例,以及使用準則。這個練習的目標是把這些知識整合起來:在一個受明確規則約束的強制相等比較系統中,實作一個搜尋函式。

練習情境

寫一個 findAll(value, array) 函式,在 array 中找出所有與 value 符合特定強制相等規則的元素,回傳一個包含所有匹配項目的陣列。

這個練習的核心挑戰在於:規則不是直接用 == 就好,而是一套更精確的強制相等規則,涵蓋了我們在這一系列討論中見過的幾乎所有角落案例。

條件說明

  1. findAll(..) 函式接受一個值和一個陣列,並回傳一個陣列。

  2. 允許的強制相等匹配規則如下:

    • 完全相同(使用 Object.is(..)
    • 字串(空字串或只有空白字元的字串除外)可以匹配數字
    • 數字(NaN 及正負無限大除外)可以匹配字串(提示:注意 -0 的處理!)
    • null 可以匹配 undefined,反之亦然
    • boolean 只能匹配 boolean
    • 物件只能匹配完全相同的物件參考

測試範本

javascript
var myObj = { a: 2 };

var values = [null, undefined, -0, 0, 13, 42, NaN, -Infinity, Infinity, "", "0", "42", "42hello", "true", "NaN", true, false, myObj];

console.log(setsMatch(findAll(null, values), [null, undefined]) === true);
console.log(setsMatch(findAll(undefined, values), [null, undefined]) === true);
console.log(setsMatch(findAll(0, values), [0, "0"]) === true);
console.log(setsMatch(findAll(-0, values), [-0]) === true);
console.log(setsMatch(findAll(13, values), [13]) === true);
console.log(setsMatch(findAll(42, values), [42, "42"]) === true);
console.log(setsMatch(findAll(NaN, values), [NaN]) === true);
console.log(setsMatch(findAll(-Infinity, values), [-Infinity]) === true);
console.log(setsMatch(findAll(Infinity, values), [Infinity]) === true);
console.log(setsMatch(findAll("", values), [""]) === true);
console.log(setsMatch(findAll("0", values), [0, "0"]) === true);
console.log(setsMatch(findAll("42", values), [42, "42"]) === true);
console.log(setsMatch(findAll("42hello", values), ["42hello"]) === true);
console.log(setsMatch(findAll("true", values), ["true"]) === true);
console.log(setsMatch(findAll(true, values), [true]) === true);
console.log(setsMatch(findAll(false, values), [false]) === true);
console.log(setsMatch(findAll(myObj, values), [myObj]) === true);

console.log(setsMatch(findAll(null, values), [null, 0]) === false);
console.log(setsMatch(findAll(undefined, values), [NaN, 0]) === false);
console.log(setsMatch(findAll(0, values), [0, -0]) === false);
console.log(setsMatch(findAll(42, values), [42, "42hello"]) === false);
console.log(setsMatch(findAll(25, values), [25]) === false);
console.log(setsMatch(findAll(Infinity, values), [Infinity, -Infinity]) === false);
console.log(setsMatch(findAll("", values), ["", 0]) === false);
console.log(setsMatch(findAll("false", values), [false]) === false);
console.log(setsMatch(findAll(true, values), [true, "true"]) === false);
console.log(setsMatch(findAll(true, values), [true, 1]) === false);
console.log(setsMatch(findAll(false, values), [false, 0]) === false);

// ***************************

function setsMatch(arr1, arr2) {
    if (Array.isArray(arr1) && Array.isArray(arr2) && arr1.length == arr2.length) {
        for (let v of arr1) {
            if (!arr2.includes(v)) return false;
        }
        return true;
    }
    return false;
}

詳細解法將在下一篇說明。

此文章是 FrontendMasters 上的 Deep JavaScript Foundations, v3 課程筆記

最後更新時間:

Buy Me A Coffee

系列章節 第 28 篇 / 共 51 篇

0 %
MIT Licensed | Copyright © 2025-present Wen-Hsiu's Blog
Photo by Federica Galli on Unsplash