溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JS容易出錯的坑有哪些

發(fā)布時間:2021-09-22 10:52:27 來源:億速云 閱讀:143 作者:小新 欄目:web開發(fā)

這篇文章將為大家詳細講解有關JS容易出錯的坑有哪些,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

. VS = 操作符優(yōu)先級

let a = {n : 1};       let b = a;       a.x = a = {n: 2};               console.log(a.x)       console.log(b.x)

輸出是什么呢?

真的想明白了嗎?

undefined  { n : 2}

你真的了解作用域嗎

var a = 0,             b = 0;       function A(a) {           A = function (b) {               console.log(a + b++)           }           console.log(a++)       }       A(1)       A(2)

留給你們思考,我可是第一遍就做錯了(;′⌒`)

答案 1 4

可以好好想一想,你會茅塞頓開的。

類數組的length

var obj = {           "2" : 3,           "3" : 4,           "length" : 2,           "splice" : Array.prototype.splice,           "push" : Array.prototype.push       }       obj.push(1)       obj.push(2)       console.log(obj)

這段代碼的執(zhí)行結果?

答案:Object(4) [empty × 2, 1, 2, splice: ƒ, push: ƒ]

JS容易出錯的坑有哪些

解釋就是第一次使用push,obj對象的push方法設置obj[2] = 1,obj.length++  解釋就是第一次使用push,obj對象的push方法設置obj[3] = 2,obj.length++  使用console.log()方法輸出的時候,因為obj上有l(wèi)ength屬性和splice方法,故將其作為數組輸出打印  打印時因為數組未設置下標為0和1的值,故打印的結果就是empty,主動獲取obj[0] = undefined

非匿名自執(zhí)行函數,函數名只讀

var b = 10;       (function b(){           // 'use strict'           b = 20           console.log(b)       })()

輸出的結果是什么?

Function b
- 如標題一樣,非匿名自執(zhí)行函數,函數名不可以修改,嚴格模式下會TypeError, - 非嚴格模式下,不報錯,修改也沒有用。 - 查找變量b時,立即執(zhí)行函數會有內部作用域,會先去查找是否有b變量的聲明,有的話,直接復制 - 確實發(fā)現具名函數Function b(){} 所以就拿來做b的值 - IIFE的函數內部無法進行復制(類似于const)

非匿名自執(zhí)行函數 II

var b = 10;       (function b(){           // 'use strict'           var b = 20           console.log(window.b)            console.log(b)       })()

輸出是多少呢?

10 20 // 訪問b變量的時候,發(fā)現var b = 20;在當前作用域中找到了b變量,于是把b的值作為20

非匿名自執(zhí)行函數 III

var b = 10;       (function b(){           console.log(b)           b = 5           console.log(window.b)           var b = 20           console.log(b)       })()

輸出的結果是多少呢?

這個問題應該不難,就留給你們思考吧

變量提升

var name = 'World!'; (function () {     if (typeof name === 'undefined') {         var name = 'Jack';         console.log('Goodbye ' + name);     } else {         console.log('Hello ' + name);     } })();

在 JavaScript中, Fun 和 var 會被提升

相當于

var name = 'World!'; (function () {     var name;     if (typeof name === 'undefined') {         name = 'Jack';         console.log('Goodbye ' + name);     } else {         console.log('Hello ' + name);     } })();

鞏固一下:

var str = 'World!';       (function (name) {    if (typeof name === 'undefined') {        var name = 'Jack';        console.log('Goodbye ' + name);    } else {        console.log('Hello ' + name);    }    })(str);    答案:Hello World 因為name已經變成函數內局部變量

最大整數

var END = Math.pow(2, 53); var START = END - 100; var count = 0; for (var i = START; i <= END; i++) {     count++; } console.log(count);

一個知識點:Infinity

在 JS 里, Math.pow(2, 53) == 9007199254740992 是可以表示的最大值. 最大值加一還是最大值. 所以循環(huán)不會停.

稀疏數組與密數組

var ary = [0,1,2]; ary[10] = 10; ary.filter(function(x) { return x === undefined;});

執(zhí)行結果如何呢?

做這個題目,你需要了解稀疏數組和密集數組

  • 譯 JavaScript中的稀疏數組與密集數組

  • Array/filter

看過源碼的同學應該知道,filter源碼中,會去判斷數組的這個索引值是不是數組的一個屬性,有興趣的同學可以看看我寫的這篇關于數組的:[干貨?]從詳細操作js數組到淺析v8中array.js

0 in ary; => true 3 in ary; => false 10 in ary; => true 也就是說 從 3 - 9 都是沒有初始化的'坑'!, 這些索引并不存在與數組中. 在 array 的函數調用的時候是會跳過這些'坑'的.

所以答案就是[]

浮點運算

var two   = 0.2 var one   = 0.1 var eight = 0.8 var six   = 0.6 [two - one == one, eight - six == two]

你認為結果是多少呢?面試遇到這個問題,應該怎么回答呢?

[true,false]

可以看看這些文章:

  • 探尋 JavaScript 精度問題以及解決方案

  • 從0.1+0.2=0.30000000000000004再看JS中的Number類型

Switch

function showCase(value) {     switch(value) {     case 'A':         console.log('Case A');         break;     case 'B':         console.log('Case B');         break;     case undefined:         console.log('undefined');         break;     default:         console.log('Do not know!');     } } showCase(new String('A'));

運行結果如何呢?

switch 是嚴格比較, String 實例和 字符串不一樣. 答案自然是'Do not know'  所以一般情況下,寫switch語句,也建議寫default

String("A")

function showCase2(value) {     switch(value) {     case 'A':         console.log('Case A');         break;     case 'B':         console.log('Case B');         break;     case undefined:         console.log('undefined');         break;     default:         console.log('Do not know!');     } } showCase2(String('A'));

運行結果呢?

答案:Case A 解析:String('A')就是返回一個字符串

%運算符

function isOdd(num) {     return num % 2 == 1; } function isEven(num) {     return num % 2 == 0; } function isSane(num) {     return isEven(num) || isOdd(num); } var values = [7, 4, '13', -9, Infinity]; values.map(isSane);

運行的結果如何呢?

答案:[true, true, true, false, false] 解析:%如果不是數值會調用Number()去轉化      '13' % 2       // 1       Infinity % 2  //NaN  Infinity 是無窮大       -9 % 2        // -1 鞏固:9 % -2        // 1   余數的正負號隨第一個操作數

數組的原型是什么

Array.isArray( Array.prototype )

這段代碼的執(zhí)行結果?

答案:true 解析:Array.prototype是一個數組 數組的原型是數組,對象的原型是對象,函數的原型是函數

寬松相等 ==

[]==[]

答案是什么呢

答案:false 解析:兩個引用類型, ==比較的是引用地址

== 和 !優(yōu)先級

[]== ![]

結果是什么呢?

(1)! 的優(yōu)先級高于== ,右邊Boolean([])是true,取返等于 false (2)一個引用類型和一個值去比較 把引用類型轉化成值類型,左邊0 (3)所以 0 == false  答案是true

數字與字符串相加減

'5' + 3 '5' - 3

結果是多少呢?

答案:53  2 解析:加號有拼接功能,減號就是邏輯運算 鞏固:typeof (+"1")   // "number" 對非數值+&mdash;常被用來做類型轉換相當于Number()

一波騷操作  + - + + + - +

1 + - + + + - + 1

結果是多少呢

答案:2 解析:+-又是一元加和減操作符號,就是數學里的正負號。負負得正哈。  鞏固: 一元運算符還有一個常用的用法就是將自執(zhí)行函數的function從函數聲明變成表達式。       常用的有 + - ~ !void       + function () { }       - function () { }       ~ function () { }       void function () { }

又是稀疏數組?Array.prototype.map()

var ary = Array(3); ary[0]=2 ary.map(function(elem) { return '1'; });

輸出結果是多少呢?

稀疏數組  題目中的數組其實是一個長度為3, 但是沒有內容的數組, array 上的操作會跳過這些未初始化的'坑'.  所以答案是 ["1", empty &times; 2]

這里貼上 Array.prototype.map 的 polyfill.

Array.prototype.map = function(callback, thisArg) {          var T, A, k;          if (this == null) {             throw new TypeError(' this is null or not defined');         }          var O = Object(this);         var len = O.length >>> 0;         if (typeof callback !== 'function') {             throw new TypeError(callback + ' is not a function');         }         if (arguments.length > 1) {             T = thisArg;         }         A = new Array(len);         k = 0;         while (k < len) {             var kValue, mappedValue;             if (k in O) {                 kValue = O[k];                 mappedValue = callback.call(T, kValue, k, O);                 A[k] = mappedValue;             }             k++;         }         return A;     };

JS是如何存儲

var a = 111111111111111110000, b = 1111; a + b;

這段代碼的執(zhí)行結果?

答案:11111111111111111000 解析:在JavaScript中number類型在JavaScript中以64位(8byte)來存儲。 這64位中有符號位1位、指數位11位、實數位52位。 2的53次方時,是最大值。 其值為:9007199254740992(0x20000000000000)。 超過這個值的話,運算的結果就會不對.

數組比較大小

var a = [1, 2, 3],     b = [1, 2, 3],     c = [1, 2, 4] a ==  b a === b a >   c a <   c

這段代碼的執(zhí)行結果?

答案:false, false, false, true 解析:相等(==)和全等(===)還是比較引用地址      引用類型間比較大小是按照字典序比較,就是先比第一項誰大,相同再去比第二項。

三元運算符優(yōu)先級

var val = 'smtg'; console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing');

這段代碼的執(zhí)行結果?

答案:Something 解析:字符串連接比三元運算有更高的優(yōu)先級       所以原題等價于 'Value is true' ? 'Somthing' : 'Nonthing'       而不是 'Value   is' + (true ? 'Something' : 'Nonthing') 鞏固:     1 || fn() && fn()   //1       1 || 1 ? 2 : 3 ;    //2

原型

var a = {}, b = Object.prototype; [a.prototype === b, Object.getPrototypeOf(a) === b]

執(zhí)行結果是多少呢

答案:false, true 解析:Object 的實例是 a,a上并沒有prototype屬性      a的__poroto__ 指向的是Object.prototype,也就是Object.getPrototypeOf(a)。a的原型對象是b

原型II

function f() {} var a = f.prototype, b = Object.getPrototypeOf(f); a === b

這段代碼的執(zhí)行結果?

答案:false 解析:a是構造函數f的原型 : {constructor: &fnof;} b是實例f的原型對象 : &fnof; () { [native code] }

函數名稱

function foo() { } var oldName = foo.name; foo.name = "bar"; [oldName, foo.name]

代碼執(zhí)行結果是什么?

答案:["foo", "foo"] 解析:函數的名字不可變.

[typeof null, null instanceof Object]

答案:["object", false] 解析:null代表空對象指針,所以typeof判斷成一個對象??梢哉fJS設計上的一個BUG      instanceof 實際上判斷的是對象上構造函數,null是空當然不可能有構造函數 鞏固:null == undefined //true    null === undefined //flase

[ [3,2,1].reduce(Math.pow), [].reduce(Math.pow) ]

答案:Error 解析:Math.pow (x , y)  x 的 y 次冪的值      reduce(fn,total)      fn (total, currentValue, currentIndex, arr)           如果一個函數不傳初始值,數組第一個組默認為初始值.          [3,2,1].reduce(Math.pow)          Math.pow(3,2) //9          Math.pow(9,1) //9  鞏固題,可以做一做:   [].reduce(Math.pow)       //空數組會報TypeError      [1].reduce(Math.pow)      //只有初始值就不會執(zhí)行回調函數,直接返回1      [].reduce(Math.pow,1)     //只有初始值就不會執(zhí)行回調函數,直接返回1      [2].reduce(Math.pow,3)    //傳入初始值,執(zhí)行回調函數,返回9

replace

"1 2 3".replace(/\d/g, parseInt)

輸出是什么呢?

答案:"1 NaN 3" 解析:replace() 回調函數的四個參數:       1、匹配項         2、與模式中的子表達式匹配的字符串         3、出現的位置         4、stringObject 本身 。 如果沒有與子表達式匹配的項,第二參數為出現的位置.所以第一個參數是匹配項,第二個參數是位置  parseInt('1', 0)  parseInt('2', 2)  //2進制中不可能有2  parseInt('3', 4)

eval用法

function f() {} var parent = Object.getPrototypeOf(f); f.name // ? parent.name // ? typeof eval(f.name) // ? typeof eval(parent.name) //  ?

這段代碼的執(zhí)行結果?

答案:"f", "Empty", "function", error 解析:f的函數名就是f      parent是f原型對象的名字為"" ,      先計算eval(f.name) 為 f,f的數據類型是function      eval(parent.name) 為undefined, "undefined"

new  Date()

var a = new Date("2014-03-19"), b = new Date(2014, 03, 19); [a.getDay() === b.getDay(), a.getMonth() === b.getMonth()]

這段代碼的執(zhí)行結果?

答案:[false, false] 解析:var a = new Date("2014-03-19")    //能夠識別這樣的字符串,返回想要的日期       Wed Mar 19 2014 08:00:00 GMT+0800 (CST)       b = new Date(2014, 03, 19);       //參數要按照索引來       Sat Apr 19 2014 00:00:00 GMT+0800 (CST)       月是從0索引,日期是從1        getDay()是獲取星期幾       getMonth()是獲取月份所以都不同 鞏固: [a.getDate() === b.getDate()] //true

new  Date() II

var a = Date(0); var b = new Date(0); var c = new Date(); [a === b, b === c, a === c]

這段代碼的執(zhí)行結果?

答案:[false, false, false] 解析:當日期被作為構造函數調用時,它返回一個相對于劃時代的對象(JAN 01 1970)。 當參數丟失時,它返回當前日期。當它作為函數調用時,它返回當前時間的字符串表示形式。 a是字符串   a === b // 數據類型都不同,肯定是false b是對象     b === c // 引用類型,比的是引用地址 c也是對象   a === c // 數據類型都不同,肯定是false

new  Date() III

var a = new Date("epoch")

你認為結果是多少呢?

答案:Invalid Date {} 解析:您得到“無效日期”,這是一個實際的日期對象(一個日期的日期為true)。但無效。這是因為時間內部保持為一個數字,在這種情況下,它是NA。       在chrome上是undefined        正確的是格式是var d = new Date(year, month, day, hours, minutes, seconds, milliseconds);

Function.length

var a = Function.length, b = new Function().length a === b

這段代碼的執(zhí)行結果是?

答案:false 解析:首先new在函數帶()時運算優(yōu)先級和.一樣所以從左向右執(zhí)行      new Function() 的函數長度為0 鞏固:function fn () {          var a = 1;       }       console.log(fn.length)        //0 fn和new Function()一樣
  • 要是看過往期的這篇文章[誠意滿滿?]帶你填一些JS容易出錯的坑 就可以給我點個贊?關注一下啦,下面的內容都是這篇文章的內容。

[1,2,5,10].sort()

不寫回調函數的話,是按照什么排序呢?

JavaScript默認使用字典序(alphanumeric)來排序。因此結果是[1,10,2,5]

正確排序的話,應該[1,2,5,10].sort( (a,b) => a-b )

"b" + "a" + +"a" + "a"

你認為輸出是什么?

上面的表達式相當于'b'+'a'+ (+'a')+'a',因為(+'a')是NaN,所以:

'b'+'a'+ (+'a')+'a' = 'b'+'a'+ "NaN"+'a'='baNaNa'

閉包

這是一個經典JavaScript面試題

let res = new Array()        for(var i = 0; i < 10; i++){            res.push(function(){                return console.log(i)            })        }        res[0]()         res[1]()        res[2]()

期望輸出的是0,1,2,實際上卻不會。原因就是涉及作用域,怎么解決呢?

  • [x] 使用let代替var,形成塊級作用域

  • [x] 使用bind函數。

res.push(console.log.bind(null, i))

解法還有其他的,比如使用IIFE,形成私有作用域等等做法。

又一經典閉包問題

function fun(n,o) {   console.log(o)   return {     fun:function(m){       return fun(m,n);     }   }; } var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);//undefined,?,?,? var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,? var c = fun(0).fun(1);  c.fun(2);  c.fun(3);//undefined,?,?,?

留給你們思考

隱式轉換

var a = [0]; if (a) {   console.log(a == true); } else {   console.log("wut"); }

你們覺得答案是多少呢?這題涉及到隱式轉換了,這個坑我自己的好好補一補

// 答案:false

再來一道?

function fn() {     return 20; } console.log(fn + 10); // 輸出結果是多少
function fn() {     return 20; } fn.toString = function() {     return 10; } console.log(fn + 10);  // 輸出結果是多少?
function fn() {     return 20; }  fn.toString = function() {     return 10; }  fn.valueOf = function() {     return 5; }  console.log(fn + 10); // 輸出結果是多少?

說到底JS類型轉換的好好補一補了

你真的理解操作符嗎

[1<2<3,3<2<1] //[false,false] //[true,true] //[false,true] //[true,false]

選一個吧,比較操作符,賦值運算符優(yōu)先級哪個更高呢?

0.1+0.2 !== 0.3 ?

面試的時候,問你這個問題,要是回答錯誤的話,估計面試官對基礎很是懷疑!!!

問你這個題目的時候,你可以牽扯出很多問題,比如JS如何存儲小數的呢?比如聊一聊二進制,比如實際開發(fā)中,遇到精度的問題,你是怎么解決的,你有什么好辦法。

聊完這個,你可以牽扯出最大安全數,比如JavaScript的最大安全整數是多少,超出這個范圍的話,怎么解決精度問題呢?

ES規(guī)范中新提出的BigInt解決了什么問題呢,你又發(fā)現了BigInt中哪些坑呢?

如何解決精度問題呢?

這里推薦Number-Precision庫,不到1K的體積。

arguments

function sidEffecting(ary) {           ary[0] = ary[2];       }       function bar(a, b, c) {           c = 10           sidEffecting(arguments);           return a + b + c;       }       function demo (arg) {           arg.name = 'new Name'       }       console.log(bar(2, 2, 2))

涉及到ES6語法,這題答案肯定都會做是22,但是呢,稍微改變一下題目,就比較坑了&hellip;.

function sidEffecting(ary) {           ary[0] = ary[2];       }       function bar(a, b, c = 4) {           c = 10           sidEffecting(arguments);           return a + b + c;       }       function demo (arg) {           arg.name = 'new Name'       }       console.log(bar(2, 2, 2))

這個答案是多少呢?根據MDN上對argument有更加準確的定義,看argument

  • 當非嚴格模式中的函數有包含剩余參數、默認參數和解構賦值,那么arguments對象中的值不會跟蹤參數的值(反之亦然)。

找到這句話,bar函數存在默認參數,并且在非嚴格模式下,所以不會跟蹤參數的值,自然結果就14

請讀者細細體會

瀏覽器

let demo1 = {class: "Animal", name: 'sheet'};       console.log(demo1.class)

比較流氓,這個跟瀏覽器相關,class是保留字(現在的話,class是關鍵字),答案并不要緊,重要的是自己在取屬性名稱的時候盡量避免保留字.  如果使用的話請加引號 a['class']。

保留字vs關鍵字

個人理解的話,關鍵字就是有特殊含義的,不用用作變量名。比如

let class = 123;

現在看來肯定報錯,那有什么需要我們注意的呢?

let undefined = 123;

這樣子并不會報錯,這個跟瀏覽器有點關系,這樣子看來undefined不是關鍵字。所以為了保險起見,建議大家在判斷一個變量是不是未定義的話,盡量使用void  0 === undefined 很有可能undefined會被當作是變量來賦值

void 0 值就是undefined

["1", "2", "3"].map(parseInt)

這個應該是經常遇見的題了,搞明白很簡單,map函數怎么使用,parseInt函數怎么使用

關于Array數組的話,我之前寫了一篇文章,從源碼角度解析大部分方法

點進去重溫一遍:[干貨?]從詳細操作js數組到淺析v8中array.js

map接受兩個參數,一個callback,一個this,即調用函數時this指向,其中callback回調函數是三個參數,一個currentValue,index,array;

parseInt接受兩個參數:string,radix(基數)

返回NaN有兩種情況

  • radix 小于 2 或大于 36 ,或

  • 第一個非空格字符不能轉換為數字。

  • 當radix是0或者undefined時,又是特殊情況,具體異步MDN

parseInt('1', 0); parseInt('2', 1); parseInt('3', 2);

兩者結合的話,結果自然很明顯,[1,NaN,NaN]

Math.min() 為什么比 Math.max() 大?

Math.min() < Math.max() // false

按照常規(guī)思路的話,應該是true,畢竟最小值應該小于最大值,但是實際情況是false

原因:

  • Math.min 的參數是 0 個或者多個。如果是多個參數很容易理解,返回參數中最小的。

  • 如果是0個參數,或者沒有參數,則返回 Infinity。

  • 而 Math.max() 沒有傳遞參數時返回的是 -Infinity。

要是面試官問這個問題,額。。。。

[].concat[1,2,3]

輸出是什么?注意不是[].concat([1,2,3])

// [1,2,3]  // Uncaught SyntaxError: ....  // undefined

答案是undefined,原因是什么呢?

第一步計算[].concat,結果是Array.prototype.concat

第二步執(zhí)行一個逗號操作符,逗號操作符對它的每個操作對象求值(從左至右),然后返回最后一個操作對象的值。

>1,2,3 返回3

第三步執(zhí)行一個數組訪問運算或屬性訪問運算

所以上面[].concat[1,2,3] 等價于Array.prototype.concat[3]

那么結果自然就是 undefined。

[1,2,NaN,3].indexOf(NaN)

//2 or -1

indexOf方法會進行嚴格相等判斷

NaN !== NaN

怎么辦呢?

let realIsNaN = value => typeof value === 'number' && isNaN(value);

先要判斷類型,是因為字符串轉換會先轉換成數字,轉換失敗為 NaN。所以和 NaN 相等。

isNaN('jjjj') &mdash;> true

第二種方法

let realIsNaN = value => value !== value;

Number.isFinite & isFinite

Number.isFinite('0') === isFinite('0')  Number.isFinite(0) === isFinite('0')

打印結果是什么,能不能具體說一說?

Number.isFinite()檢測有窮性的值,唯一和全局isFinite()函數相比,這個方法不會強制將一個非數值的參數轉換成數值,這就意味著,只有數值類型的值,且是有窮的(finite),才返回  true。

自然答案就是 false,true

一道容易被人輕視的面試題

function Foo() {     getName = function () { alert (1); };     return this; } Foo.getName = function () { alert (2);}; Foo.prototype.getName = function () { alert (3);}; var getName = function () { alert (4);}; function getName() { alert (5);}  //請寫出以下輸出結果: Foo.getName(); getName(); Foo().getName(); getName(); new Foo.getName(); new Foo().getName(); new new Foo().getName();

push方法

let newList = [1,2,3].push(4) console.log(newList.push(4))

認為輸出什么?

// Error

原因在于Array.prototype.push()返回的是新數組的長度,所以呢4.push(5)自然Error

自動分號插入

function foo1() {  return {      bar: "hello"  }; }  function foo2() {  return  {      bar: "hello"  }; } var a=foo1(); var b=foo2(); console.log(a) //Object {bar: "hello"} console.log(b) //underfind //仔細看就知道了 // 會在第10行加入一個`;`

會在第10行自動加一個分號; 所以返回的就是undefined

let var

function foo() { let a = b = 0; a++; return a; } foo(); typeof a; // => ??? typeof b; // => ???

上面的let a = b = 0; 等價于 window.b = 0, let a = b;

眼力題

const length = 4; const numbers = []; for (var i = 0; i < length; i++);{   numbers.push(i + 1); }  numbers; // => ???

唯一需要注意的就是for語句后面帶了;沙雕題

加了;,會認為for執(zhí)行完,所以指定的都是空語句,最后numbers為[5]

獲取字符串中特定索引字符

console.log('Hello World'[4])

使用的就是方括號表示法獲取字符串特定索引的字符,值得注意的是,IE7低版本使用的是charAt()

所以這題輸出o

!==

const name = 'TianTianUp' console.log(!typeof name === 'string') console.log(!typeof name === 'object')

typeof name 返回的是 &rsquo;string&lsquo;, 字符串&rsquo;string&lsquo;是一個truthy值。因此!typeof name  返回一個布爾值false。所以

false === &rsquo;string'

和 false === &rsquo;object&lsquo;返回false

(檢測一個類型的值話,我們應該使用 !==而不是!typeof)

forEach

const nums = [1, 2, 3, 4, 5, 6]; let firstEven; nums.forEach(n => {   if (n % 2 ===0 ) {     firstEven = n;     return n;   } }); console.log(firstEven);

唯一需要注意的就是forEach源碼是怎么寫的,看過源碼的都知道,forEach使用return是不能中止循環(huán)的,或者說每一次調用callback函數,終止的是當前的一次,而不是整個循環(huán)。

結果自然就是6

關于“JS容易出錯的坑有哪些”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI