var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
ฉันเห็นมันในคำตอบและฉันไม่เคยเห็นมันมาก่อน
มันหมายความว่าอะไร?
var attr = ~'input,textarea'.indexOf( target.tagName.toLowerCase() )
? 'value'
: 'innerHTML'
ฉันเห็นมันในคำตอบและฉันไม่เคยเห็นมันมาก่อน
มันหมายความว่าอะไร?
คำตอบ:
~
เป็นตัวดำเนินการระดับบิตที่พลิกบิตทั้งหมดในตัวถูกดำเนินการ
ตัวอย่างเช่นหากหมายเลขของคุณคือ1
การแสดงเลขฐานสองของโฟลว์ IEEE 754 (วิธีที่จาวาสคริปต์จัดการกับตัวเลข) จะเป็น ...
0011 1111 1111 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
ดังนั้น~
แปลงตัวถูกดำเนินการเป็นจำนวนเต็ม 32 บิต (ตัวดำเนินการ bitwise ใน JavaScript ทำอย่างนั้น) ...
0000 0000 0000 0000 0000 0000 0000 0001
ถ้ามันเป็นจำนวนลบมันจะถูกเก็บไว้ในส่วนเติมเต็มของ 2: สลับบิตทั้งหมดและเพิ่ม 1
... จากนั้นจึงพลิกบิตทั้งหมด ...
1111 1111 1111 1111 1111 1111 1111 1110
แล้วการใช้งานของมันคืออะไร? เมื่อใดบ้างที่ผู้ใช้อาจใช้
มันมีการใช้งานค่อนข้างน้อย หากคุณกำลังเขียนเนื้อหาระดับต่ำมันมีประโยชน์ หากคุณทำโปรไฟล์แอปพลิเคชันของคุณและพบคอขวดอาจทำให้นักแสดงมีประสิทธิภาพมากขึ้นโดยใช้เทคนิคบิตทริก (เป็นเครื่องมือหนึ่งที่เป็นไปได้ในกระเป๋าใบใหญ่)
นอกจากนี้ยังเป็น (โดยทั่วไป) ไม่ชัดเจนเคล็ดลับที่จะเปิดindexOf()
's พบค่าตอบแทนเข้าtruthy (ในขณะที่ทำให้ไม่พบเป็น falsy ) และผู้คนมักจะใช้มันสำหรับผลข้างเคียงของการตัดทอนหมายเลขที่ 32 บิต (และลดลงทศนิยมตำแหน่งของตนโดยการเพิ่มมัน ได้ผลเช่นเดียวกับMath.floor()
ตัวเลขบวก)
ฉันพูดไม่ชัดเจนเพราะไม่ชัดเจนในทันทีว่ามันใช้งานอะไร โดยทั่วไปแล้วคุณต้องการให้โค้ดสื่อสารกับผู้อื่นที่อ่านรหัสอย่างชัดเจน ในขณะที่ใช้งาน~
อาจดูเย็นก็มักฉลาดเกินไปสำหรับการที่ดีของตัวเอง :)
นอกจากนี้ยังมีความเกี่ยวข้องน้อยในขณะนี้ว่ามี JavaScript และArray.prototype.includes()
String.prototype.includes()
สิ่งเหล่านี้คืนค่าบูลีน หากแพลตฟอร์มเป้าหมายของคุณสนับสนุนคุณควรใช้วิธีนี้ในการทดสอบการมีอยู่ของค่าในสตริงหรืออาร์เรย์
value = value || default
ใน JavaScript เป็นสำนวนที่ใช้กันทั่วไปและถูกต้องตราบใดที่คุณรู้เมื่อคุณสามารถและไม่สามารถใช้มันได้
v = t ? a : b;
อาจจะเป็นตัวอย่างที่พบมากคือ ฉันพบว่าชัดเจนกว่าvar v; if (t} { v = a; } else { v = b; }
ปกติเสียมากกว่า5+ บรรทัดและชัดเจนกว่าvar v = b; if (t) { v = a; }
ปกติซึ่งจะเป็น 4+ บรรทัด แต่ฉันรู้ว่าผู้คนจำนวนมากไม่คุ้นเคยกับ? :
ผู้ให้บริการที่ต้องการวิธีที่สองหรือสาม ฉันพบว่าคนแรกอ่านง่ายขึ้น ฉันเห็นด้วยกับหลักการทั่วไปทำให้รหัสชัดเจนไม่ใช้แฮ็ก ฉันคิดว่าฉันเห็น~v.indexOf('...')
ชัดเจนมากเมื่อฉันเรียนรู้แล้ว
~
สำนวน มันเป็นส่วนหนึ่งของภาษาสเปคแต่มันก็ไม่ได้เป็นส่วนมากของภาษาในการใช้งานทั่วไป
ใช้มันก่อน indexOf()
แสดงออกอย่างมีประสิทธิภาพจะช่วยให้คุณได้ผลลัพธ์ที่เป็นจริง / เป็นเท็จแทนดัชนีตัวเลขที่ส่งคืนโดยตรง
หากค่าส่งคืนเป็น-1
เช่นนั้น~-1
เป็น0
เพราะ-1
สตริงของ 1 บิตทั้งหมด ค่าใด ๆ ที่มากกว่าหรือเท่ากับศูนย์จะให้ผลลัพธ์ที่ไม่เป็นศูนย์ ดังนั้น
if (~someString.indexOf(something)) {
}
จะทำให้if
รหัสทำงานเมื่อ "บางอย่าง" อยู่ใน "someString" ถ้าคุณลองใช้.indexOf()
เป็นบูลีนโดยตรงสิ่งนั้นจะไม่ทำงานเพราะบางครั้งมันกลับเป็นศูนย์ (เมื่อ "บางสิ่ง" อยู่ที่จุดเริ่มต้นของสตริง)
แน่นอนว่ามันก็ใช้ได้เช่นกัน:
if (someString.indexOf(something) >= 0) {
}
และมันลึกลับน้อยกว่ามาก
บางครั้งคุณจะเห็นสิ่งนี้ด้วย:
var i = ~~something;
การใช้ตัว~
ดำเนินการสองครั้งเช่นนี้เป็นวิธีที่รวดเร็วในการแปลงสตริงเป็นจำนวนเต็ม 32 บิต อย่างแรก~
คือการแปลงและครั้งที่สองก็~
พลิกบิตกลับ แน่นอนว่าถ้าโอเปอเรเตอร์ถูกนำไปใช้กับบางสิ่งที่ไม่สามารถแปลงเป็นตัวเลขได้คุณจะได้NaN
ผลลัพธ์ ( แก้ไข - อันที่จริงมันเป็นตัวที่สอง~
ที่ใช้ก่อน แต่คุณจะได้แนวคิด)
~
-(x + 1)
0
เรื่องของความเป็นอยู่false
และไม่เป็นศูนย์ซึ่งtrue
ย้อนกลับไปได้อย่างน้อยก็ถึง C ในยุค 70 และอาจเป็นภาษาโปรแกรมอื่น ๆ มันอาจเกิดจากวิธีการทำงานของฮาร์ดแวร์ CPU จำนวนมากตั้งค่าบิตศูนย์หลังจากการดำเนินการและมีคำสั่งสาขาที่สอดคล้องกันเพื่อทดสอบ
| 0
ในกรณีนี้การดำเนินการเดียวเท่านั้น
~~
ลักษณะเดียวกัน
~
เป็นBitwise ไม่ Operator , เป็นประมาณเช่นเดียวกับ~x
-(x+1)
ง่ายต่อการเข้าใจเรียงลำดับจาก ดังนั้น:
~2; // -(2+1) ==> -3
-(x+1)
พิจารณา สามารถดำเนินการดังกล่าวในการผลิต-1
0
กล่าวอีกนัยหนึ่งการ~
ใช้กับช่วงของค่าตัวเลขจะสร้างค่า falsy (coerce to false
from 0
) เฉพาะ-1
ค่าอินพุตเท่านั้นมิฉะนั้นค่าจริงอื่น ๆ
อย่างที่เรารู้ -1
เป็นเรื่องปกติที่เรียกว่าค่าแมวมอง มันจะใช้สำหรับฟังก์ชั่นมากมายที่กลับ>= 0
ค่าสำหรับความสำเร็จและ-1
สำหรับความล้มเหลวในภาษา C ซึ่งมีกฎการคืนค่าเหมือนกันindexOf()
ใน JavaScript
มันเป็นเรื่องธรรมดาที่จะตรวจสอบว่ามี / ไม่มีซับสตริงในสตริงอื่นด้วยวิธีนี้
var a = "Hello Baby";
if (a.indexOf("Ba") >= 0) {
// found it
}
if (a.indexOf("Ba") != -1) {
// found it
}
if (a.indexOf("aB") < 0) {
// not found
}
if (a.indexOf( "aB" ) == -1) {
// not found
}
อย่างไรก็ตามมันจะง่ายกว่าที่จะทำผ่าน~
ดังต่อไปนี้
var a = "Hello Baby";
~a.indexOf("Ba"); // -7 -> truthy
if (~a.indexOf("Ba")) { // true
// found it
}
~a.indexOf("aB"); // 0 -> falsy
!~a.indexOf("aB"); // true
if (!~a.indexOf( "aB" )) { // true
// not found
}
-(x+1)
ถ้าฉันเห็นมันในคำสั่ง if ตัวหนอนบอกฉันว่าสิ่งที่ทำเพื่อชดเชยธรรมชาติที่ใช้ 0 ของ Javascript นอกจากนี้วงเล็บที่น้อยกว่าจะดีกว่าสำหรับการอ่าน
if (a.indexOf("Ba") > -1) {// found} //true
สิ่งที่แม้ว่าบิตที่ยาวกว่าตัวอย่างตัวหนอนจะน้อยกว่าตัวอย่างสองตัวอย่างที่คุณให้และสำหรับโปรแกรมเมอร์ใหม่ที่var opinion = !~-1 ? 'more' : 'less'
เข้าใจได้
~indexOf(item)
เกิดขึ้นบ่อยครั้งและคำตอบที่นี่ยอดเยี่ยม แต่บางทีบางคนก็ต้องรู้วิธีใช้และ "ข้าม" ทฤษฎี:
if (~list.indexOf(item)) {
// item in list
} else {
// item *not* in list
}
++
และ--
เพราะพวกเขา "กระตุ้นให้เกิดความยุ่งยากมากเกินไป" และยังมี~
ชีวิตรอด (ซ่อนตัวอยู่ในเงามืด) github.com/airbnb/javascript/issues/540
list.indexOf(item) >= 0
หรือ... > -1
เนื่องจาก javascript มีพื้นฐานเป็นศูนย์และไม่ได้เลือกที่จะแก้ไขปัญหานี้ตั้งแต่เริ่มแรก เพิ่มเติมเพียงแค่ความเห็น (เช่นเดียวกับ Airbnb) ทุกคนที่ทำสิ่งที่มีความหมายในจาวาสคริปต์รู้++
และในขณะที่--
เป็นเรื่องธรรมดาน้อยกว่าความหมายที่สามารถอนุมาน
++
และ--
ในขณะที่เพราะวิธีดั้งเดิมเช่นmap
, forEach
ฯลฯ จุดของฉันคือเพิ่มเติมเกี่ยวกับเหตุผลที่พวกเขาไม่ได้พิจารณา~
เรื่องยุ่งยากมากเกินไปเมื่อสิ่งที่มาตรฐานที่ใช้รวมถึงการเพิ่มขึ้นและลดลงผู้ประกอบการ เพื่อห้ามบางสิ่งบางอย่างดังนั้น CIS101 จึงไม่สมเหตุสมผล
สำหรับการพิจารณาการใช้เคล็ดลับตัวหนอนเพื่อสร้างtruthyค่าจากindexOf
ผลก็เป็นที่ชัดเจนมากขึ้นและมีความวิเศษน้อยแทนที่จะใช้วิธีการในการincludes
String
'hello world'.includes('hello') //=> true
'hello world'.includes('kittens') //=> false
โปรดทราบว่านี่เป็นวิธีมาตรฐานใหม่ของ ES 2015 ดังนั้นจึงไม่สามารถใช้กับเบราว์เซอร์รุ่นเก่าได้ ในกรณีที่สำคัญให้พิจารณาใช้String.prototype.includes polyfill polyfill
คุณลักษณะนี้มีให้สำหรับอาร์เรย์ที่ใช้ไวยากรณ์เดียวกัน :
['apples', 'oranges', 'cherries'].includes('apples') //=> true
['apples', 'oranges', 'cherries'].includes('unicorns') //=> false
นี่คือArray.prototype.includes polyfillหากคุณต้องการการสนับสนุนเบราว์เซอร์รุ่นเก่า