日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁(yè) > 科技  > 軟件

小心這個(gè)陷阱: 為什么JS中的 Every()對(duì)空數(shù)組總返回 True

來(lái)源: 責(zé)編: 時(shí)間:2023-09-20 21:55:54 347觀看
導(dǎo)讀JavaScript 語(yǔ)言的核心部分足夠大,以至于我們很容易誤解其某些部分的工作方式。最近在重構(gòu)一些使用 every() 方法的代碼時(shí),發(fā)現(xiàn)實(shí)際上并不理解其背后的邏輯。在我的理解中,我認(rèn)為回調(diào)函數(shù)必須被調(diào)用并返回true , every()

doU28資訊網(wǎng)——每日最新資訊28at.com

JavaScript 語(yǔ)言的核心部分足夠大,以至于我們很容易誤解其某些部分的工作方式。最近在重構(gòu)一些使用 every() 方法的代碼時(shí),發(fā)現(xiàn)實(shí)際上并不理解其背后的邏輯。在我的理解中,我認(rèn)為回調(diào)函數(shù)必須被調(diào)用并返回true , every() 才會(huì)返回 true ,但實(shí)際上并非如此。對(duì)于一個(gè)空數(shù)組, every() 無(wú)論回調(diào)函數(shù)是什么都會(huì)返回 true ,因?yàn)槟莻€(gè)回調(diào)函數(shù)從未被調(diào)用過(guò)。考慮以下情況:doU28資訊網(wǎng)——每日最新資訊28at.com

function isNumber(value) {    return typeof value === "number";}[1].every(isNumber);            // true["1"].every(isNumber);          // false[1, 2, 3].every(isNumber);      // true[1, "2", 3].every(isNumber);    // false[].every(isNumber);             // true

在這個(gè)例子的每個(gè)情況中,對(duì) every() 的調(diào)用都會(huì)檢查數(shù)組中的每個(gè)項(xiàng)目是否為數(shù)字。前四次調(diào)用相當(dāng)直接, every() 產(chǎn)生了預(yù)期的結(jié)果。現(xiàn)在考慮以下這些例子:doU28資訊網(wǎng)——每日最新資訊28at.com

[].every(() => true);           // true[].every(() => false);          // true

這可能更令人驚訝:返回 true 或 false 的回調(diào)函數(shù)具有相同的結(jié)果。這只能發(fā)生的唯一原因是如果回調(diào)函數(shù)沒(méi)有被調(diào)用,而 every() 的默認(rèn)值是 true 。但是,為什么在沒(méi)有值來(lái)運(yùn)行回調(diào)函數(shù)時(shí),空數(shù)組會(huì)返回 true 給 every() 呢?doU28資訊網(wǎng)——每日最新資訊28at.com

要理解為什么,我們需要仔細(xì)看看規(guī)范是如何描述這個(gè)方法的。doU28資訊網(wǎng)——每日最新資訊28at.com

實(shí)現(xiàn) every()

ECMA-262 定義了一個(gè) Array.prototype.every()  算法,大致可以翻譯成這段JavaScript代碼:doU28資訊網(wǎng)——每日最新資訊28at.com

Array.prototype.every = function(callbackfn, thisArg) {    const O = this;    const len = O.length;    if (typeof callbackfn !== "function") {        throw new TypeError("Callback isn't callable");    }    let k = 0;    while (k < len) {        const Pk = String(k);        const kPresent = O.hasOwnProperty(Pk);        if (kPresent) {            const kValue = O[Pk];            const testResult = Boolean(callbackfn.call(thisArg, kValue, k, O));            if (testResult === false) {                return false;            }        }        k = k + 1;    }    return true;};

從代碼中,你可以看到 every() 假設(shè)結(jié)果是 true ,并且只有在回調(diào)函數(shù)對(duì)數(shù)組中的任何一項(xiàng)返回 false 時(shí)才返回 false 。如果數(shù)組中沒(méi)有任何項(xiàng)目,那么就沒(méi)有機(jī)會(huì)執(zhí)行回調(diào)函數(shù),因此,該方法無(wú)法返回 false 。doU28資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)在的問(wèn)題是:為什么 every() 會(huì)表現(xiàn)出這樣的行為?doU28資訊網(wǎng)——每日最新資訊28at.com

在數(shù)學(xué)和JavaScript中的“對(duì)所有”的量詞

MDN頁(yè)面 提供了為什么 every() 會(huì)對(duì)空數(shù)組返回 true 的答案:doU28資訊網(wǎng)——每日最新資訊28at.com

every 的行為就像數(shù)學(xué)中的“全稱量詞”。特別是對(duì)于空數(shù)組,它返回真值。(空集中的所有元素都滿足任何給定條件,這是顯然的真理。)doU28資訊網(wǎng)——每日最新資訊28at.com

空真(Vacuous truth)是一個(gè)數(shù)學(xué)概念,意味著如果給定的條件(稱為前件)不能被滿足(即給定的條件不為真),那么某件事就是真的。用JavaScript的術(shù)語(yǔ)來(lái)說(shuō),every() 對(duì)于一個(gè)空集合返回 true,因?yàn)闆](méi)有辦法調(diào)用回調(diào)函數(shù)。回調(diào)函數(shù)代表要測(cè)試的條件,如果由于數(shù)組中沒(méi)有值而無(wú)法執(zhí)行它,那么 every() 必須返回 true。doU28資訊網(wǎng)——每日最新資訊28at.com

“全稱量詞”("for all" quantifier)是數(shù)學(xué)中更大主題“全稱量化”(universal quantification)的一部分,它允許你對(duì)數(shù)據(jù)集進(jìn)行推理。考慮到JavaScript數(shù)組在進(jìn)行數(shù)學(xué)計(jì)算方面的重要性,尤其是在使用類型數(shù)組(typed arrays)的情況下,內(nèi)置支持這樣的操作是合理的。而**every()**方法并不是唯一的例子。doU28資訊網(wǎng)——每日最新資訊28at.com

在數(shù)學(xué)和JavaScript中的“存在量詞”

JavaScript的 some() 方法實(shí)現(xiàn)了存在量化(existential quantification)中的“存在量詞”(“存在”有時(shí)也被稱為“存在”或“對(duì)某些”)。這個(gè)“存在量詞”規(guī)定,對(duì)于任何空集合,結(jié)果都是假的。因此,some() 方法對(duì)空集合返回 false,并且也不會(huì)執(zhí)行回調(diào)函數(shù)。以下是一些相關(guān)的示例:doU28資訊網(wǎng)——每日最新資訊28at.com

function isNumber(value) {    return typeof value === "number";}[1].some(isNumber);            // true["1"].some(isNumber);          // false[1, 2, 3].some(isNumber);      // true[1, "2", 3].some(isNumber);    // true[].some(isNumber);             // false[].some(() => true);           // false[].some(() => false);          // false

其他語(yǔ)言中的量化

JavaScript并不是唯一實(shí)現(xiàn)了集合或可迭代對(duì)象的量化方法的編程語(yǔ)言:doU28資訊網(wǎng)——每日最新資訊28at.com

  • Python: all() 函數(shù)實(shí)現(xiàn)了“對(duì)所有”  ,而 any() 函數(shù)實(shí)現(xiàn)了“存在”  。
  • Rust: Iterator::all() 方法實(shí)現(xiàn)了“對(duì)所有”  ,而 any() 函數(shù)實(shí)現(xiàn)了“存在” 。

“全稱量詞”(for all)的 every() 方法的含義與影響

無(wú)論你是否認(rèn)為 every() 方法的行為違反直覺(jué)都是可以討論的。然而,無(wú)論你的觀點(diǎn)如何,你都需要了解 every() 的“全稱量詞”(for all)特性以避免錯(cuò)誤。簡(jiǎn)而言之,如果你使用 every() 方法或可能為空的數(shù)組,你應(yīng)該事先進(jìn)行明確的檢查。例如,如果你有一個(gè)依賴于數(shù)字?jǐn)?shù)組的操作,并且在數(shù)組為空時(shí)會(huì)失敗,那么在使用 every() 之前,你應(yīng)該檢查數(shù)組是否為空。doU28資訊網(wǎng)——每日最新資訊28at.com

function doSomethingWithNumbers(numbers) {    // first check the length    if (numbers.length === 0) {        throw new TypeError("Numbers array is empty; this method requires at least one number.");    }    // now check with every()    if (numbers.every(isNumber)) {        operationRequiringNonEmptyArray(numbers);    }}

再次強(qiáng)調(diào),只有當(dāng)你有一個(gè)數(shù)組在為空時(shí)不應(yīng)該被用于操作時(shí),這才重要;否則,你可以避免這個(gè)額外的檢查。doU28資訊網(wǎng)——每日最新資訊28at.com

結(jié)論

當(dāng)我第一次看到 every() 在空數(shù)組上的行為時(shí),我感到很驚訝,但一旦你理解了這個(gè)操作的更大背景和這個(gè)功能在各種語(yǔ)言中的廣泛應(yīng)用,就會(huì)覺(jué)得它是有道理的。如果你也對(duì)這個(gè)行為感到困惑,那么我建議你改變閱讀 every() 調(diào)用的方式。不要把 every() 理解為“這個(gè)數(shù)組中的每一項(xiàng)是否都符合這個(gè)條件?”而應(yīng)該理解為“這個(gè)數(shù)組中是否有任何一項(xiàng)不符合這個(gè)條件?”這種思維方式的轉(zhuǎn)變可以幫助你避免在未來(lái)的JavaScript代碼中出現(xiàn)錯(cuò)誤。doU28資訊網(wǎng)——每日最新資訊28at.com

doU28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-10557-0.html小心這個(gè)陷阱: 為什么JS中的 Every()對(duì)空數(shù)組總返回 True

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: Spring強(qiáng)大的數(shù)據(jù)格式化處理功能,你必須得知道

下一篇: Github的一個(gè)奇技淫巧,你學(xué)會(huì)了嗎?

標(biāo)簽:
  • 熱門焦點(diǎn)
Top 主站蜘蛛池模板: 丽水市| 中方县| 崇仁县| 韶山市| 辽宁省| 昆明市| 普安县| 宝兴县| 大庆市| 洪雅县| 瑞昌市| 佛学| 灵璧县| 浮山县| 靖远县| 禹城市| 开阳县| 新沂市| 马山县| 加查县| 赤峰市| 靖安县| 新昌县| 嵊州市| 深州市| 繁峙县| 车致| 游戏| 三穗县| 内乡县| 宁远县| 明光市| 堆龙德庆县| 封开县| 新建县| 静宁县| 乌兰浩特市| 博爱县| 孟村| 黄龙县| 卢龙县|