ฉันพบว่ามีบางคนเรียก JavaScript ว่าเป็นภาษา "แบบไดนามิกและพิมพ์ผิด" แต่บางคนถึงกับพูดว่า "ไม่พิมพ์"? ซึ่งจริงๆแล้ว?
ฉันพบว่ามีบางคนเรียก JavaScript ว่าเป็นภาษา "แบบไดนามิกและพิมพ์ผิด" แต่บางคนถึงกับพูดว่า "ไม่พิมพ์"? ซึ่งจริงๆแล้ว?
คำตอบ:
JavaScript ไม่ได้พิมพ์ :
(ที่มา: no.gd )
แม้แต่ Brendan Eich ก็พูดเช่นนั้น ใน Twitter เขาตอบกระทู้ที่เชื่อมโยงกับคำถามนี้:
ดังนั้นปัญหาคือว่ามีคำจำกัดความที่แตกต่างกันไม่กี่untyped
มีการพูดถึงคำจำกัดความหนึ่งคำในหนึ่งในคำตอบข้างต้น - รันไทม์ไม่ได้แท็กค่าและถือว่าแต่ละค่าเป็นบิต JavaScript ทำค่าแท็กและมีลักษณะการทำงานที่แตกต่างกันตามแท็กเหล่านั้น เห็นได้ชัดว่า JavaScript ไม่เหมาะกับหมวดหมู่นี้
คำจำกัดความอื่น ๆ มาจากProgramming Language Theory (สิ่งทางวิชาการที่ Brendan อ้างถึง) ในโดเมนนี้untypedเพียงหมายถึงทุกอย่างที่เป็นชนิดเดียว
ทำไม? เนื่องจากภาษาจะสร้างโปรแกรมก็ต่อเมื่อสามารถพิสูจน์ได้ว่าประเภทสอดคล้องกัน (aka the Curry-Howard การโต้ตอบประเภทคือทฤษฎีบทโปรแกรมเป็นเครื่องพิสูจน์) ซึ่งหมายความว่าในภาษาที่ไม่ได้พิมพ์:
ตรงกันข้ามกับภาษาที่พิมพ์:
ดังนั้นมีคุณไปใน PLT, untypedเพียงวิธีการพิมพ์แบบไดนามิกและการพิมพ์เพียงหมายถึงการพิมพ์แบบคงที่ JavaScript ไม่ถูกพิมพ์ในหมวดหมู่นี้อย่างแน่นอน
ดูสิ่งนี้ด้วย:
1. 2. 3.
สำหรับภาษา untyped ไม่ตรงกับ JavaScript ไม่ได้มีเพียงประเภทเดียว - มีประมาณ 4 - 5 ดังนั้นการสาธิต JavaScript จึงไม่ถูกพิมพ์อย่างไร?
แข็งแรง / อ่อนแอ สามารถคิดได้โดยสัมพันธ์กับวิธีที่คอมไพเลอร์จัดการกับการพิมพ์
พิมพ์ผิดหมายความว่าคอมไพเลอร์ถ้ามีไม่บังคับให้พิมพ์ถูกต้อง หากไม่มีคำอุทานคอมไพเลอร์โดยนัยคำสั่งจะผิดพลาดระหว่างรันไทม์
"12345" * 1 === 12345 // string * number => number
พิมพ์ขอหมายถึงมีความเป็นคอมไพเลอร์และมันต้องการให้คุณโยนอย่างชัดเจนจากสตริงเพื่อจำนวนเต็ม
(int) "12345" * 1 === 12345
ไม่ว่าในกรณีใดคุณลักษณะบางอย่างของคอมไพเลอร์สามารถเปลี่ยนแปลงคำสั่งโดยปริยายระหว่างเวลาคอมไพล์เพื่อทำการแปลงให้คุณได้หากสามารถระบุได้ว่าเป็นสิ่งที่ควรทำ
ป่านนี้ JavaScript สามารถจัดประเภทเป็น Not-Strongly-Typed นั่นหมายความว่ามันพิมพ์ผิดหรือไม่ได้พิมพ์
ไดนามิก / คงที่ สามารถคิดได้โดยสัมพันธ์กับวิธีการที่คำสั่งภาษาจัดการกับประเภทต่างๆ
การพิมพ์แบบไดนามิกหมายถึงประเภทของค่าถูกบังคับใช้ แต่ตัวแปรเพียงแค่แทนค่าประเภทใดก็ได้
x = 12345; // number
x = "string"; // string
x = { key: "value" }; // object
y = 123 + x; // error or implicit conversion must take place.
การพิมพ์แบบคงที่หมายถึงประเภทตัวแปรถูกบังคับใช้อย่างมากและประเภทค่าจะถูกบังคับใช้น้อย
int x = 12345; // binds x to the type int
x = "string"; // too late, x is an integer - error
string y = 123; // error or implicit conversion must take place.
ป่านนี้ JavaScript สามารถจัดประเภทเป็น Not-Statically-Typed ได้ นอกจากนี้ดูเหมือนว่าจะพิมพ์แบบไดนามิกหากพิมพ์เลย ดังนั้นเราต้องดูว่าการพิมพ์หมายถึงอะไร
พิมพ์วิธีการที่แตกต่างระหว่างภาษาที่แตกต่างกันเช่นสตริง ,จำนวน ,บูล ,วัตถุ ,อาเรย์ , null , undefinedและอื่น ๆ นอกจากนี้การดำเนินการแต่ละอย่างจะถูกผูกไว้กับประเภทเฉพาะ คุณจึงไม่สามารถหารจำนวนเต็มด้วยสตริงได้
2 / "blah" // produces NaN
untypedหมายถึงการดำเนินงานของการหารจำนวนเต็มโดยสตริงจะส่งผลในการรักษาสี่ไบต์แรกของสตริงเป็นจำนวนเต็ม เนื่องจากการดำเนินการที่ไม่ได้พิมพ์เกิดขึ้นโดยตรงบนบิตจึงไม่มีประเภทที่ต้องสังเกต ผลลัพธ์จะเป็นสิ่งที่ไม่คาดคิด:
2 / "blah" // will be treated as 2 / 1500275048
เนื่องจาก JavaScript ทำงานตามคำจำกัดความของการพิมพ์จึงต้องเป็น ดังนั้นจึงต้องพิมพ์แบบไดนามิกและพิมพ์ผิดปกติ
หากมีใครอ้างว่า JavaScript ไม่ได้พิมพ์เป็นเพียงทฤษฎีทางวิชาการไม่ใช่เพื่อการประยุกต์ใช้งานจริง
จาวาสคริปต์พิมพ์ผิด แน่นอนที่สุดไม่ใช่ "ไม่พิมพ์" แต่ลักษณะการพิมพ์ที่ไม่ชัดเจนทำให้เกิดความยืดหยุ่นในแง่ของการแปลงโดยนัย
โปรดทราบว่า JavaScript ถูกพิมพ์แบบไดนามิกด้วยเช่นกัน วิธีการนี้จะช่วยให้การพิมพ์สิ่งที่เป็นความรู้เป็น"เป็ดพิมพ์"
สำหรับการเปรียบเทียบโปรดพิจารณาว่า JavaScript ไม่ได้ถูกพิมพ์อย่างรุนแรงหรือพิมพ์แบบคงที่ บางครั้งการทำความเข้าใจว่าอะไรบางอย่างไม่สามารถช่วยให้คุณเห็นสิ่งที่ดีขึ้นได้
ปัญหาที่สร้างความสับสนให้กับโปรแกรมเมอร์จำนวนมากคือคำจำกัดความเช่นนี้ไม่ได้มาตรฐาน คำว่าภาษาโปรแกรมที่ไม่พิมพ์มีความคลุมเครือ นั่นหมายถึงภาษาที่ไม่มีชนิดข้อมูลหรือภาษาที่เป็นตัวแปรที่ไม่มีการพิมพ์แคลคูลัสแลมบ์ดาหรือไม่?
JavaScript / ECMAScript มีระบบประเภทและโดเมนของฟังก์ชันทั้งหมดจะยอมรับประเภทข้อกำหนดอ้างอิงใด ๆ นั่นหมายความว่า JavaScript มีประเภทข้อมูลเดียวในความเป็นจริง นั่นเป็นเรื่องของการนำไปใช้งานที่มีความสำคัญมากกว่าสำหรับโปรแกรมเมอร์ JavaScript ขั้นสูง โปรแกรมเมอร์ JavaScript โดยเฉลี่ยสนใจเฉพาะประเภทข้อมูลภาษานามธรรม ที่ ECMAScript ระบุเท่านั้น
ในบริบทของโปรแกรมเมอร์ในชีวิตประจำวันไม่ได้เป็นนักวิจัยหรือนักวิทยาศาสตร์คอมพิวเตอร์ทฤษฎีคำว่าuntypedคือการเรียกชื่อผิดเพราะคนส่วนใหญ่ไม่ได้ทำแคลคูลัสแลมบ์ดา ดังนั้นคำนี้สร้างความสับสนให้กับมวลชนและดูเหมือนว่าจะประกาศว่า JavaScript ไม่มีประเภทข้อมูลใด ๆ ซึ่งไม่เป็นความจริง ทุกคนที่เคยใช้จะtypeof
รู้ว่า JavaScript มีประเภทข้อมูลภาษาของตัวเอง:
var test = "this is text";
typeof(test);
ผลตอบแทน
"สตริง"
ECMAScript กำหนดประเภทต่อไปนี้สำหรับภาษา: undefined
, null
, string
, boolean
, number
,object
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
การกำหนดที่แม่นยำยิ่งขึ้นสำหรับ JavaScript จะเป็นการพิมพ์โดยปริยายพิมพ์แบบไดนามิกหรือพิมพ์อย่างอ่อน / หลวม (หรือรวมกันบางอย่าง) ใน JavaScript นั้นใช้การบังคับประเภทในบางกรณีซึ่งทำให้ประเภทมีนัยเนื่องจากคุณไม่จำเป็นต้องระบุอย่างชัดเจน ประเภทของตัวแปรของคุณ มันอยู่ภายใต้การพิมพ์ที่อ่อนแอเนื่องจากไม่เหมือนกับภาษาบางภาษาที่แยกความแตกต่างระหว่างnumber
จำนวนทศนิยมและจำนวนเต็ม ฯลฯ เพียงแค่ใช้ประเภทเดียวเพื่อรวมตัวเลขทั้งหมดและใช้การบังคับประเภทที่กล่าวถึงก่อนหน้านี้[มาตรา 9 ของ ECMAScript Spec]ซึ่งตรงกันข้ามกับ a ภาษาที่พิมพ์ยากซึ่งจะมีประเภทข้อมูลที่เฉพาะเจาะจงมาก (เช่นคุณจะต้องระบุint
หรือfloat
)
คำจำกัดความของภาษาที่พิมพ์แบบคงที่และแบบไดนามิกนั้นไม่ได้เป็นมาตรฐานอย่างไรก็ตามทั้งสองก็ไม่มีขนาดของไบต์เมื่อคอมพิวเตอร์เริ่มมีวิวัฒนาการ การพิมพ์แบบคงที่และแบบไดนามิกส่วนใหญ่มักอ้างถึงคุณสมบัติของภาษาบางอย่าง ซึ่งเป็นหนึ่งในประเภทของการตรวจสอบที่รันไทม์หรือสิ่งที่เรียกว่าแบบไดนามิกประเภทการตรวจสอบ หากคุณเคยใช้ JavaScript คุณรู้อยู่แล้วว่าต้องรอจนกว่ารันไทม์จะตรวจสอบประเภทซึ่งเป็นสาเหตุที่คุณได้รับTypeError
ข้อยกเว้นระหว่างการเรียกใช้โค้ดของคุณ ตัวอย่างที่นี่
ผมคิดว่าด้านบนลงคะแนนคำตอบที่เป็นความสับสนpolymorphism ฟังก์ชัน JavaScriptที่มีฟังก์ชั่นที่จะยอมรับอะไร (เช่นเดียวกับสายพันธุ์ untyped ของแลมบ์ดาแคลคูลัส) อย่างแท้จริงซึ่งเป็นสมาคมการเข้าใจผิด
โปรดจำไว้ว่า JavaScript ช่วยให้คุณสามารถขอให้สิ่งที่เป็นtypeof(your_variable)
และเปรียบเทียบประเภทผลตอบแทน5==="5"
false
ฉันไม่คิดว่าคุณจะเรียกมันว่าไม่พิมพ์ได้
เป็นแบบไดนามิกและ (ประมาณว่า) พิมพ์ผิด คุณอาจต้องการทราบว่ามันใช้การพิมพ์เป็ด (ดูลิงก์ของแอนดรูว์) และเสนอ OOP ผ่านการสร้างต้นแบบแทนการเรียนและการสืบทอด
String a = "blah";
หรือvar a:String = 'blah';
(เช่นตัวแปรที่พิมพ์) ได้เลย นั่นคือเหตุผลที่ไม่ได้พิมพ์
ในขณะที่พิมพ์อยู่ (คุณสามารถถาม "typeof someVar" และเรียนรู้ประเภทเฉพาะของมันได้ แต่มันก็อ่อนแอมาก
ให้:
var a = "5";
คุณอาจบอกว่า a คือสตริง อย่างไรก็ตามหากคุณเขียน:
var b = a + 10;
b คือ int เท่ากับ 15 ดังนั้นการกระทำก็เหมือนกับ int แน่นอนคุณสามารถเขียน:
var c = a + "Hello World";
และ c จะเท่ากับ "5Hello World" ดังนั้น a จึงทำหน้าที่เหมือนสตริงอีกครั้ง