รายการตัวอย่าง JavaScript ที่ตลกและยุ่งยาก
JavaScript เป็นภาษาที่ยอดเยี่ยม มีรูปแบบที่เรียบง่าย มีระบบนิเวศขนาดใหญ่ และที่สำคัญที่สุดคือมีชุมชนที่ยอดเยี่ยม
ในขณะเดียวกัน เราทุกคนก็รู้ดีว่า JavaScript เป็นภาษาที่ค่อนข้างตลกและมีส่วนที่ยุ่งยาก บางส่วนสามารถเปลี่ยนงานประจำวันของเราให้กลายเป็นนรกได้อย่างรวดเร็ว และบางส่วนอาจทำให้เราหัวเราะออกมาดัง ๆ
แนวคิดดั้งเดิมสำหรับ WTFJS เป็นของ Brian Leroux รายการนี้ได้รับแรงบันดาลใจอย่างมากจากการบรรยายเรื่อง “WTFJS” ของเขาที่ dotJS 2012:
คุณสามารถติดตั้งคู่มือนี้โดยใช้ npm
เพียงแค่เรียกใช้:
$ npm install -g wtfjs
คุณควรจะสามารถเรียกใช้ wtfjs
ที่บรรทัดคำสั่งได้ทันที นี่จะเป็นการเปิดคู่มือใน $PAGER
ที่คุณเลือก มิฉะนั้นคุณสามารถอ่านต่อได้ที่นี่
แหล่งที่มามีอยู่ที่นี่: https://github.com/denysdovhan/wtfjs
ปัจจุบันมีคำแปลของ wtfjs เหล่านี้:
ช่วยแปลเป็นภาษาของคุณ
หมายเหตุ: การแปลได้รับการดูแลโดยนักแปล อาจไม่มีทุกตัวอย่าง และตัวอย่างที่มีอยู่อาจล้าสมัย
[]
เท่ากัน ![]
true
ไม่เท่ากับ ![]
แต่ก็ไม่เท่ากับ []
เช่นกันNaN
ไม่ใช่ NaN
Object.is()
และ ===
กรณีแปลก ๆ[]
จริงแต่ไม่ true
null
เป็นเท็จ แต่ไม่ใช่ false
document.all
เป็นวัตถุ แต่ไม่ได้กำหนดไว้undefined
และ Number
parseInt
เป็นคนเลวtrue
และ false
NaN
เป็น[]
และ null
เป็นวัตถุ0.1 + 0.2
String
constructor
__proto__
`${{Object}}`
try..catch
arguments
และฟังก์ชันลูกศรNumber.toFixed()
แสดงตัวเลขที่แตกต่างกันMath.max()
น้อยกว่า Math.min()
null
กับ 0
{}{}
ไม่ได้กำหนดไว้arguments
ที่มีผลผูกพันalert
จากนรกsetTimeout
true
อย่างไม่เข้มงวดเพียงเพื่อความสนุกสนาน
— “เพียงเพื่อความสนุก: เรื่องราวของการปฏิวัติโดยบังเอิญ” โดย Linus Torvalds
เป้าหมายหลักของรายการนี้คือการรวบรวมตัวอย่างแปลกๆ และอธิบายวิธีการทำงาน หากเป็นไปได้ เพียงเพราะมันสนุกที่จะเรียนรู้สิ่งที่เราไม่เคยรู้มาก่อน
หากคุณเป็นมือใหม่ คุณสามารถใช้บันทึกย่อเหล่านี้เพื่อเจาะลึก JavaScript ได้ ฉันหวังว่าบันทึกเหล่านี้จะกระตุ้นให้คุณใช้เวลาอ่านข้อกำหนดมากขึ้น
หากคุณเป็นนักพัฒนามืออาชีพ คุณสามารถพิจารณาตัวอย่างเหล่านี้เป็นข้อมูลอ้างอิงที่ดีเยี่ยมสำหรับลักษณะเฉพาะและข้อดีที่ไม่คาดคิดของ JavaScript ที่เราชื่นชอบ
ยังไงก็ลองอ่านเรื่องนี้ดูนะครับ คุณคงจะได้พบกับสิ่งใหม่ๆ
หมายเหตุ: หากคุณสนุกกับการอ่านเอกสารนี้ โปรดพิจารณาสนับสนุนผู้เขียนคอลเลกชันนี้
// ->
ใช้เพื่อแสดงผลลัพธ์ของนิพจน์ ตัวอย่างเช่น:
1 + 1 ; // -> 2
// >
หมายถึงผลลัพธ์ของ console.log
หรือเอาต์พุตอื่น ตัวอย่างเช่น:
console . log ( "hello, world!" ) ; // > hello, world!
//
เป็นเพียงความคิดเห็นที่ใช้สำหรับการอธิบาย ตัวอย่าง:
// Assigning a function to foo constant
const foo = function ( ) { } ;
[]
เท่ากัน ![]
อาร์เรย์เท่ากับไม่ใช่อาร์เรย์:
[ ] == ! [ ] ; // -> true
ตัวดำเนินการความเท่าเทียมกันเชิงนามธรรมจะแปลงทั้งสองด้านให้เป็นตัวเลขเพื่อเปรียบเทียบ และทั้งสองฝ่ายจะกลายเป็นเลข 0
ด้วยเหตุผลที่แตกต่างกัน อาร์เรย์นั้นเป็นค่าความจริง ดังนั้นทางด้านขวา สิ่งที่ตรงกันข้ามกับค่าความจริงก็คือ false
ซึ่งจากนั้นจะถูกบังคับให้เป็น 0
อย่างไรก็ตาม ทางด้านซ้าย อาร์เรย์ว่างจะถูกบังคับให้เป็นตัวเลขโดยไม่ต้องกลายเป็นบูลีนก่อน และอาร์เรย์ว่างจะถูกบังคับให้เป็น 0
แม้ว่าจะเป็นค่าจริงก็ตาม
ต่อไปนี้คือวิธีที่นิพจน์นี้ทำให้ง่ายขึ้น:
+ [ ] == + ! [ ] ;
0 == + false ;
0 == 0 ;
true ;
ดูเพิ่มเติมที่ []
เป็นความจริงแต่ไม่เป็น true
!
)true
ไม่เท่ากับ ![]
แต่ก็ไม่เท่ากับ []
เช่นกัน Array ไม่เท่ากัน true
แต่ไม่ใช่ Array ก็ไม่เท่ากัน true
เช่นกัน Array ก็เท่ากับ false
ไม่ใช่ Array ก็เท่ากับ false
เช่นกัน:
true == [ ] ; // -> false
true == ! [ ] ; // -> false
false == [ ] ; // -> true
false == ! [ ] ; // -> true
true == [ ] ; // -> false
true == ! [ ] ; // -> false
// According to the specification
true == [ ] ; // -> false
toNumber ( true ) ; // -> 1
toNumber ( [ ] ) ; // -> 0
1 == 0 ; // -> false
true == ! [ ] ; // -> false
! [ ] ; // -> false
true == false ; // -> false
false == [ ] ; // -> true
false == ! [ ] ; // -> true
// According to the specification
false == [ ] ; // -> true
toNumber ( false ) ; // -> 0
toNumber ( [ ] ) ; // -> 0
0 == 0 ; // -> true
false == ! [ ] ; // -> true
! [ ] ; // -> false
false == false ; // -> true
! ! "false" == ! ! "true" ; // -> true
! ! "false" === ! ! "true" ; // -> true
พิจารณาทีละขั้นตอนนี้:
// true is 'truthy' and represented by value 1 (number), 'true' in string form is NaN.
true == "true" ; // -> false
false == "false" ; // -> false
// 'false' is not the empty string, so it's a truthy value
! ! "false" ; // -> true
! ! "true" ; // -> true
"b" + "a" + + "a" + "a" ; // -> 'baNaNa'
นี่เป็นเรื่องตลกในโรงเรียนเก่าใน JavaScript แต่ได้รับการปรับปรุงใหม่ นี่คือต้นฉบับ:
"foo" + + "bar" ; // -> 'fooNaN'
นิพจน์ได้รับการประเมินเป็น 'foo' + (+'bar')
ซึ่งจะแปลง 'bar'
ไม่ใช่ตัวเลข
+
)NaN
ไม่ใช่ NaN
NaN === NaN ; // -> false
ข้อกำหนดกำหนดตรรกะเบื้องหลังพฤติกรรมนี้อย่างเคร่งครัด:
- ถ้า
Type(x)
แตกต่างจากType(y)
ให้ส่งคืน false- ถ้า
Type(x)
เป็น Number แล้ว
- ถ้า
x
เป็น NaN ให้คืนค่า false- ถ้า
y
เป็น NaN ให้คืนค่า false- -
— 7.2.14 การเปรียบเทียบความเท่าเทียมกันอย่างเข้มงวด
ตามคำจำกัดความของ NaN
จาก IEEE:
ความสัมพันธ์ที่แยกจากกันไม่ได้เกิดขึ้นได้ 4 แบบ คือ น้อยกว่า เท่ากับ มากกว่า และไม่เรียงลำดับ กรณีสุดท้ายเกิดขึ้นเมื่ออย่างน้อยหนึ่งตัวถูกดำเนินการคือ NaN NaN ทุกอันจะต้องเปรียบเทียบอย่างไม่เป็นระเบียบกับทุกสิ่ง รวมถึงตัวมันเองด้วย
— “อะไรคือเหตุผลสำหรับการเปรียบเทียบทั้งหมดที่ส่งคืนค่าเท็จสำหรับค่า IEEE754 NaN” ที่ StackOverflow
Object.is()
และ ===
กรณีแปลก ๆ Object.is()
กำหนดว่าค่าสองค่ามีค่าเท่ากันหรือไม่ มันทำงานคล้ายกับตัวดำเนินการ ===
แต่มีกรณีแปลก ๆ อยู่บ้าง:
Object . is ( NaN , NaN ) ; // -> true
NaN === NaN ; // -> false
Object . is ( - 0 , 0 ) ; // -> false
- 0 === 0 ; // -> true
Object . is ( NaN , 0 / 0 ) ; // -> true
NaN === 0 / 0 ; // -> false
ในภาษาจาวาสคริปต์ NaN
และ NaN
เป็นค่าเดียวกันแต่ไม่เท่ากันอย่างเคร่งครัด NaN === NaN
ที่เป็นเท็จนั้นเห็นได้ชัดว่าเกิดจากเหตุผลทางประวัติศาสตร์ ดังนั้นจึงน่าจะเป็นการดีกว่าที่จะยอมรับมันตามที่เป็นอยู่
ในทำนองเดียวกัน -0
และ 0
มีค่าเท่ากันอย่างเคร่งครัด แต่ค่าเหล่านี้ไม่เท่ากัน
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับ NaN === NaN
ดูกรณีข้างต้น
คุณจะไม่เชื่อแต่...
( ! [ ] + [ ] ) [ + [ ] ] +
( ! [ ] + [ ] ) [ + ! + [ ] ] +
( [ ! [ ] ] + [ ] [ [ ] ] ) [ + ! + [ ] + [ + [ ] ] ] +
( ! [ ] + [ ] ) [ ! + [ ] + ! + [ ] ] ;
// -> 'fail'
โดยการแยกสัญลักษณ์จำนวนมากออกเป็นชิ้นๆ เราจะสังเกตเห็นว่ารูปแบบต่อไปนี้เกิดขึ้นบ่อยครั้ง:
! [ ] + [ ] ; // -> 'false'
! [ ] ; // -> false
ดังนั้นเราจึงลองเพิ่ม []
ไปที่ false
แต่เนื่องจากการเรียกใช้ฟังก์ชันภายในจำนวนมาก ( binary + Operator
-> ToPrimitive
-> [[DefaultValue]]
) เราจึงแปลงตัวถูกดำเนินการที่ถูกต้องเป็นสตริง:
! [ ] + [ ] . toString ( ) ; // 'false'
เมื่อคิดว่าสตริงเป็นอาร์เรย์เราสามารถเข้าถึงอักขระตัวแรกได้ทาง [0]
:
"false" [ 0 ] ; // -> 'f'
ที่เหลือก็ชัดเจน แต่ i
เป็นคนยุ่งยาก i
ใน fail
ถูกคว้าโดยการสร้างสตริง 'falseundefined'
และคว้าองค์ประกอบในดัชนี ['10']
ตัวอย่างเพิ่มเติม:
+ ! [ ] // -> 0
+ ! ! [ ] // -> 1
! ! [ ] // -> true
! [ ] // -> false
[ ] [ [ ] ] // -> undefined
+ ! ! [ ] / + ! [ ] // -> Infinity
[ ] + { } // -> "[object Object]"
+ { } // -> NaN
[]
จริงแต่ไม่ true
อาร์เรย์เป็นค่าความจริง อย่างไรก็ตาม มันไม่เท่ากับ true
! ! [ ] // -> true
[ ] == true // -> false
ต่อไปนี้เป็นลิงก์ไปยังส่วนที่เกี่ยวข้องในข้อกำหนด ECMA-262:
!
)null
เป็นเท็จ แต่ไม่ใช่ false
แม้ว่าข้อเท็จจริงที่ว่า null
จะเป็นค่าเท็จ แต่ก็ไม่เท่ากับ false
! ! null ; // -> false
null == false ; // -> false
ในเวลาเดียวกัน ค่าเท็จอื่นๆ เช่น 0
หรือ ''
จะเท่ากับ false
0 == false ; // -> true
"" == false ; // -> true
คำอธิบายเหมือนกับตัวอย่างก่อนหน้า นี่คือลิงค์ที่เกี่ยวข้อง:
document.all
เป็นวัตถุ แต่ไม่ได้กำหนดไว้
นี่เป็นส่วนหนึ่งของ Browser API และจะไม่ทำงานในสภาพแวดล้อม Node.js
แม้ว่า document.all
จะเป็นออบเจ็กต์ที่มีลักษณะคล้ายอาร์เรย์และให้สิทธิ์การเข้าถึงโหนด DOM ในเพจ แต่ก็ตอบสนองต่อฟังก์ชัน typeof
เป็น undefined
document . all instanceof Object ; // -> true
typeof document . all ; // -> 'undefined'
ในขณะเดียวกัน document.all
ก็ไม่เท่ากับ undefined
document . all === undefined ; // -> false
document . all === null ; // -> false
แต่ในขณะเดียวกัน:
document . all == null ; // -> true
document.all
เคยเป็นวิธีการเข้าถึงองค์ประกอบ DOM โดยเฉพาะกับ IE เวอร์ชันเก่า แม้ว่าจะไม่เคยมีมาตรฐานมาก่อน แต่ก็มีการใช้กันอย่างแพร่หลายในโค้ด JS ยุคเก่า เมื่อมาตรฐานก้าวหน้าไปพร้อมกับ API ใหม่ (เช่นdocument.getElementById
) การเรียก API นี้ล้าสมัย และคณะกรรมการมาตรฐานต้องตัดสินใจว่าจะทำอย่างไรกับมัน เนื่องจากการใช้งานในวงกว้าง พวกเขาจึงตัดสินใจเก็บ API ไว้แต่กลับแนะนำการละเมิดข้อกำหนด JavaScript โดยเจตนา สาเหตุที่ตอบสนองต่อfalse
เมื่อใช้การเปรียบเทียบความเท่าเทียมกันอย่างเข้มงวดกับundefined
ในขณะที่true
เมื่อใช้การเปรียบเทียบความเท่าเทียมกันเชิงนามธรรม เกิดจากการจงใจละเมิดข้อกำหนดเฉพาะที่อนุญาตไว้อย่างชัดเจน— “ฟีเจอร์ที่ล้าสมัย - document.all” ที่ WhatWG - ข้อมูลจำเพาะ HTML — “บทที่ 4 - ToBoolean - ค่าเท็จ” ที่ YDKJS - ประเภทและไวยากรณ์
Number.MIN_VALUE
คือตัวเลขที่น้อยที่สุด ซึ่งมากกว่าศูนย์:
Number . MIN_VALUE > 0 ; // -> true
Number.MIN_VALUE
คือ5e-324
กล่าวคือ จำนวนบวกที่น้อยที่สุดที่สามารถแสดงด้วยความแม่นยำแบบลอยตัว กล่าวคือ จะใกล้เคียงที่สุดเท่าที่คุณจะไปถึงศูนย์ได้ มันกำหนดความละเอียดที่ดีที่สุดที่โฟลตสามารถให้คุณได้ตอนนี้ค่าที่น้อยที่สุดโดยรวมคือ
Number.NEGATIVE_INFINITY
แม้ว่าจะไม่ใช่ตัวเลขจริงๆ ก็ตามในแง่ที่เข้มงวด— “เหตุใด
0
จึงน้อยกว่าNumber.MIN_VALUE
ใน JavaScript” ที่ StackOverflow
มีข้อบกพร่องใน V8 v5.5 หรือต่ำกว่า (Node.js <=7)
ทุกท่านคงทราบดีว่า undefinition is not a function ที่น่ารำคาญ แต่แล้วสิ่งนี้ล่ะ?
// Declare a class which extends null
class Foo extends null { }
// -> [Function: Foo]
new Foo ( ) instanceof null ;
// > TypeError: function is not a function
// > at … … …
นี่ไม่ใช่ส่วนหนึ่งของข้อกำหนด มันเป็นเพียงข้อบกพร่องที่ได้รับการแก้ไขแล้ว ดังนั้นจึงไม่น่าจะมีปัญหาเกิดขึ้นอีกในอนาคต
เป็นเรื่องต่อเนื่องกับข้อผิดพลาดก่อนหน้านี้ในสภาพแวดล้อมสมัยใหม่ (ทดสอบด้วย Chrome 71 และ Node.js v11.8.0)
class Foo extends null { }
new Foo ( ) instanceof null ;
// > TypeError: Super constructor null of Foo is not a constructor
นี่ไม่ใช่ข้อผิดพลาดเนื่องจาก:
Object . getPrototypeOf ( Foo . prototype ) ; // -> null
หากคลาสไม่มีตัวสร้างการเรียกจากห่วงโซ่ต้นแบบ แต่ในพาเรนต์ไม่มีคอนสตรัคเตอร์ ในกรณีนี้ ฉันจะชี้แจงว่า null
เป็นวัตถุ:
typeof null === "object" ;
ดังนั้นคุณสามารถสืบทอดจากมันได้ (แม้ว่าในโลกของ OOP สำหรับเงื่อนไขดังกล่าวจะเอาชนะฉันได้) ดังนั้นคุณไม่สามารถเรียกตัวสร้างโมฆะได้ หากคุณเปลี่ยนรหัสนี้:
class Foo extends null {
constructor ( ) {
console . log ( "something" ) ;
}
}
คุณเห็นข้อผิดพลาด:
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
และถ้าคุณเพิ่ม super
:
class Foo extends null {
constructor ( ) {
console . log ( 111 ) ;
super ( ) ;
}
}
JS ส่งข้อผิดพลาด:
TypeError: Super constructor null of Foo is not a constructor
จะเกิดอะไรขึ้นถ้าคุณพยายามเพิ่มอาร์เรย์สองตัว?
[ 1 , 2 , 3 ] + [ 4 , 5 , 6 ] ; // -> '1,2,34,5,6'
การต่อข้อมูลเกิดขึ้น ทีละขั้นตอนจะมีลักษณะดังนี้:
[ 1 , 2 , 3 ] +
[ 4 , 5 , 6 ] [
// call toString()
( 1 , 2 , 3 )
] . toString ( ) +
[ 4 , 5 , 6 ] . toString ( ) ;
// concatenation
"1,2,3" + "4,5,6" ;
// ->
( "1,2,34,5,6" ) ;
คุณได้สร้างอาร์เรย์ที่มีองค์ประกอบว่าง 4 รายการ อย่างไรก็ตาม คุณจะได้รับอาร์เรย์ที่มีสามองค์ประกอบ เนื่องจากมีเครื่องหมายจุลภาคต่อท้าย:
let a = [ , , , ] ;
a . length ; // -> 3
a . toString ( ) ; // -> ',,'
เครื่องหมายจุลภาคต่อท้าย (บางครั้งเรียกว่า "เครื่องหมายจุลภาคสุดท้าย") อาจมีประโยชน์เมื่อเพิ่มองค์ประกอบ พารามิเตอร์ หรือคุณสมบัติใหม่ลงในโค้ด JavaScript หากคุณต้องการเพิ่มคุณสมบัติใหม่ คุณสามารถเพิ่มบรรทัดใหม่โดยไม่ต้องแก้ไขบรรทัดสุดท้ายก่อนหน้านี้ หากบรรทัดนั้นใช้เครื่องหมายจุลภาคต่อท้ายอยู่แล้ว ซึ่งจะทำให้การควบคุมเวอร์ชันต่างสะอาดขึ้น และการแก้ไขโค้ดอาจยุ่งยากน้อยลง
— เครื่องหมายจุลภาคต่อท้ายที่ MDN
ความเท่าเทียมกันของอาร์เรย์เป็นสัตว์ประหลาดใน JS ดังที่คุณเห็นด้านล่าง:
[ ] == '' // -> true
[ ] == 0 // -> true
[ '' ] == '' // -> true
[ 0 ] == 0 // -> true
[ 0 ] == '' // -> false
[ '' ] == 0 // -> true
[ null ] == '' // true
[ null ] == 0 // true
[ undefined ] == '' // true
[ undefined ] == 0 // true
[ [ ] ] == 0 // true
[ [ ] ] == '' // true
[ [ [ [ [ [ ] ] ] ] ] ] == '' // true
[ [ [ [ [ [ ] ] ] ] ] ] == 0 // true
[ [ [ [ [ [ null ] ] ] ] ] ] == 0 // true
[ [ [ [ [ [ null ] ] ] ] ] ] == '' // true
[ [ [ [ [ [ undefined ] ] ] ] ] ] == 0 // true
[ [ [ [ [ [ undefined ] ] ] ] ] ] == '' // true
คุณควรดูตัวอย่างข้างต้นอย่างระมัดระวัง! ลักษณะการทำงานอธิบายไว้ในส่วน 7.2.15 การเปรียบเทียบความเท่าเทียมกันเชิงนามธรรมของข้อกำหนด
undefined
และ Number
หากเราไม่ส่งอาร์กิวเมนต์ใด ๆ ไปยังตัวสร้าง Number
เราจะได้ 0
ค่า undefined
จะถูกกำหนดให้กับอาร์กิวเมนต์ที่เป็นทางการเมื่อไม่มีอาร์กิวเมนต์จริง ดังนั้นคุณอาจคาดหวังว่า Number
ที่ไม่มีอาร์กิวเมนต์จะ undefined
เป็นค่าของพารามิเตอร์ อย่างไรก็ตาม เมื่อเราผ่าน undefined
เราจะได้รับ NaN
Number ( ) ; // -> 0
Number ( undefined ) ; // -> NaN
ตามข้อกำหนด:
n
เป็น +0
n
เป็น ? ToNumber(value)
.undefined
ToNumber(undefined)
ควรส่งคืน NaN
นี่คือส่วนที่เกี่ยวข้อง:
argument
) parseInt
เป็นคนเลว parseInt
มีชื่อเสียงในด้านนิสัยใจคอ:
parseInt ( "f*ck" ) ; // -> NaN
parseInt ( "f*ck" , 16 ) ; // -> 15
คำอธิบาย: สิ่งนี้เกิดขึ้นเนื่องจาก parseInt
จะดำเนินการแยกวิเคราะห์อักขระต่ออักขระต่อไปจนกว่าจะกระทบกับอักขระที่ไม่รู้จัก f
ใน 'f*ck'
คือเลขฐานสิบหก 15
การแยกวิเคราะห์ Infinity
เป็นจำนวนเต็มเป็นสิ่งที่...
//
parseInt ( "Infinity" , 10 ) ; // -> NaN
// ...
parseInt ( "Infinity" , 18 ) ; // -> NaN...
parseInt ( "Infinity" , 19 ) ; // -> 18
// ...
parseInt ( "Infinity" , 23 ) ; // -> 18...
parseInt ( "Infinity" , 24 ) ; // -> 151176378
// ...
parseInt ( "Infinity" , 29 ) ; // -> 385849803
parseInt ( "Infinity" , 30 ) ; // -> 13693557269
// ...
parseInt ( "Infinity" , 34 ) ; // -> 28872273981
parseInt ( "Infinity" , 35 ) ; // -> 1201203301724
parseInt ( "Infinity" , 36 ) ; // -> 1461559270678...
parseInt ( "Infinity" , 37 ) ; // -> NaN
ระวังการแยกวิเคราะห์ null
ด้วย:
parseInt ( null , 24 ) ; // -> 23
คำอธิบาย:
กำลังแปลงค่า
null
เป็นสตริง"null"
และพยายามแปลงค่า สำหรับฐาน 0 ถึง 23 จะไม่มีตัวเลขที่สามารถแปลงได้ ดังนั้นจึงส่งกลับ NaN เมื่ออายุ 24 ตัวอักษร"n"
ซึ่งเป็นตัวอักษรตัวที่ 14 จะถูกเพิ่มเข้าไปในระบบตัวเลข ที่ตำแหน่ง 31 จะมีการเพิ่ม"u"
ซึ่งเป็นตัวอักษรตัวที่ 21 และสามารถถอดรหัสสตริงทั้งหมดได้ เมื่ออายุ 37 เป็นต้นไป ไม่มีชุดตัวเลขที่ถูกต้องที่สามารถสร้างได้อีกต่อไป และNaN
จะถูกส่งคืน— “parseInt(null, 24) === 23… เดี๋ยวก่อน อะไรนะ?” ที่ StackOverflow
อย่าลืมเกี่ยวกับเลขฐานแปด:
parseInt ( "06"