อักขระใดที่ใช้ได้กับชื่อตัวแปร JavaScript


557

อักขระใดที่สามารถใช้เพื่อตั้งชื่อตัวแปร JavaScript

ฉันต้องการสร้าง "ส่วนขยายไลบรารี" ขนาดเล็กสำหรับผู้ใช้ที่ไม่ใช่ JavaScript ของฉันที่นี่ในที่ทำงาน (ซึ่งทุกคนดูเหมือนจะคลื่นไส้เมื่อมาถึงภาษา) ฉันชอบที่ jQuery และ Prototype ต่างก็ใช้$เครื่องหมายดอลลาร์และเนื่องจากฉันใช้ jQuery ฉันกำลังมองหาสัญลักษณ์ตัวอักษรเดี่ยวที่ดีอีกตัวที่จะใช้

ฉันรู้ว่าฉันสามารถทดสอบจำนวนอักขระได้ แต่ฉันหวังที่จะ จำกัด รายชื่อตัวละครของฉันให้แคบลง (โดยคำนึงถึงอนาคตที่จะรวมเข้ากับห้องสมุดยอดนิยมอื่น ๆ )


44
NO ยอมรับตัวอักษร Unicode ได้ ลองใช้πเช่น
nalply

14
แม้ว่าตัวอักษรยูนิโค้ดเป็นที่ยอมรับในชื่อตัวแปรการใช้ Unicode ในรหัสอาจเป็นปัญหาได้ ฉันจะแนะนำไม่ใช้พวกเขาในชื่อตัวแปรถ้าคุณสามารถรับโดยไม่มีพวกเขา
Gary S. Weaver

F # เป็นชื่อตัวแปรที่ถูกต้องทำไม ฉันกำลังสร้างห้องสมุดจาวาสคริปต์ขนาดเล็กที่ใช้งานได้และฉันต้องการใช้ F # สำหรับชื่อโมดูล การเรียกใช้ฟังก์ชันทั่วไปจะมีลักษณะเช่นนี้: F # .partial (fn, ... presetArgs);
Jules Manson

@JulesManson ไม่เพราะสัญลักษณ์ปอนด์ถูกสงวนไว้สำหรับการใช้งานอื่น
Aidan Lovelace

@JulesManson โดยวิธีการชื่อ F # นำโดย Microsoft จาก. NET
Luke the Geek

คำตอบ:


986

หากต้องการอ้างอิงชื่อตัวแปร JavaScript ที่ถูกต้องบทความของฉันจะสรุปส่วนข้อมูลจำเพาะที่เกี่ยวข้อง:

ตัวระบุต้องเริ่มต้นด้วย$, _หรือตัวอักษรใด ๆ ในประเภท Unicode “พิมพ์ใหญ่ตัวอักษร (Lu)” , “ตัวพิมพ์เล็กตัวอักษร (LL)” , “ตัวอักษร Titlecase (แอล)” , “ปรับปรุงตัวอักษร (Lm)” , “ตัวอักษรอื่น ๆ ( Lo)”หรือ‘จำนวนจดหมาย (NL)’

ส่วนที่เหลือของสตริงสามารถมีอักขระเหมือนกันรวมถึงอักขระที่ไม่ใช่ตัวเชื่อมความกว้างศูนย์ U + 200Cอักขระตัวเชื่อมสัญญาณความกว้างศูนย์ U + 200Dและอักขระในหมวดหมู่ Unicode “ เครื่องหมายที่ไม่ใช่ระยะห่าง (Mn)” , “ การรวมระยะห่าง เครื่องหมาย (Mc)” , ‘เลขทศนิยมหลัก (Nd)’หรือ‘เชื่อมต่อเครื่องหมายวรรคตอน (PC)’

ฉันได้สร้างเครื่องมือที่จะบอกคุณว่าสตริงใด ๆ ที่คุณป้อนเป็นชื่อตัวแปร JavaScript ที่ถูกต้องตาม ECMAScript 5.1 และ Unicode 6.1:

เครื่องมือตรวจสอบชื่อตัวแปร JavaScript


PS เพื่อให้คุณคิดของวิธีการที่ไม่ถูกต้องคำตอบที่แอนโทนี่มิลส์เป็น: ถ้าคุณมีการสรุปกฎเหล่านี้ทั้งหมดใน ASCII เท่านั้นแสดงออกปกติเดียวสำหรับ JavaScript, มันจะเป็น 11,236 ตัวอักษร นี่มันคือ:

// ES5.1 / Unicode 6.1
/^(?!(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)$)[$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc][$A-Z\_a-z\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc0-9\u0300-\u036f\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u08fe\u0900-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d02\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19d9\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1dc0-\u1de6\u1dfc-\u1dff\u200c\u200d\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f]*$/

31
ฉันจะให้เครดิตคุณตามจำนวนเวลาที่คุณจะต้องสร้างสิ่งนี้
Richard Clayton

18
@marsbear ฉันได้เขียนบทความเกี่ยวกับเรื่องนี้เช่นกัน: mathiasbynens.be/notes/javascript-propertiesและเครื่องมือเช่นกัน: mothereff.in/js-properties#12e34นี่คือคำตอบสแต็คล้นที่เกี่ยวข้องของฉัน
Mathias Bynens

2
Dammit ดังนั้นฉันไม่สามารถรับสมาร์ทและใช้¢ในการเติมเต็ม$... โอ้ได้ดี ...)-:
hippietrail

3
มันเป็นเรื่องจริง (และเป็นคำตอบที่ยอดเยี่ยม) อย่างไรก็ตามสิ่งนี้ไม่ได้ทำให้ถูกต้อง: รหัสทำให้งงงวยโดยใช้ตัวอักษรที่ดูคล้าย แต่ในความเป็นจริงที่แตกต่างกัน (หรือการใช้ตัวอักษรที่สภาพแวดล้อมที่ไม่ใช่ยูนิโค้ดไม่สามารถใช้) คือผิด มันไม่ได้ช่วยเข้ารหัสและสามารถสร้างข้อบกพร่องมากมายแทน ข้อเสียที่ดีเพียงอย่างเดียว: มันจะทำให้ผู้คน (เจ็บปวด) ทราบถึงความเป็นไปได้ที่โค้ดบางอันใช้ Unicode (และตระหนักถึง Unicode และการเป็นตัวแทนที่แตกต่างกัน) ... เกี่ยวกับ unicode: joelonsoftware.com/articles/Unicode.html
Olivier Dulac

4
@ n2liquid-GuilhermeVieira เฉพาะในกรณีที่คุณถือว่าเอนจิ้น JavaScript ทั้งหมดเป็นไปตามข้อกำหนด 100% ซึ่งไม่ได้เป็นเช่นนั้นเสมอไป - แน่นอนว่าไม่ใช่เมื่อฉันทำการวิจัยนี้ โพสต์บล็อกที่ฉันเชื่อมโยงจะกล่าวถึงข้อผิดพลาดของเบราว์เซอร์ / เครื่องมือทั้งหมดที่ฉันยื่นและแก้ไข
Mathias Bynens

117

จากข้อกำหนดคุณสมบัติ ECMAScript ในส่วนที่7.6 ตัวระบุชื่อและตัวระบุตัวระบุที่ถูกต้องจะถูกกำหนดเป็น:

Identifier :: 
    IdentifierName but not ReservedWord

IdentifierName :: 
    IdentifierStart 
    IdentifierName IdentifierPart 

IdentifierStart :: 
    UnicodeLetter 
    $ 
    _ 
    \ UnicodeEscapeSequence 

IdentifierPart :: 
    IdentifierStart 
    UnicodeCombiningMark 
    UnicodeDigit 
    UnicodeConnectorPunctuation 
    \ UnicodeEscapeSequence 

UnicodeLetter 
    any character in the Unicode categories Uppercase letter (Lu)”, Lowercase letter (Ll)”, Titlecase letter (Lt)”, 
    Modifier letter (Lm)”, Other letter (Lo)”, or Letter number (Nl)”. 

UnicodeCombiningMark 
    any character in the Unicode categories Non-spacing mark (Mn)” or Combining spacing mark (Mc)” 

UnicodeDigit 
    any character in the Unicode category Decimal number (Nd)” 

UnicodeConnectorPunctuation 
    any character in the Unicode category Connector punctuation (Pc)” 

UnicodeEscapeSequence 
    see 7.8.4. 

HexDigit :: one of 
    0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

ซึ่งสร้างโอกาสมากมายสำหรับการตั้งชื่อตัวแปรและในการเล่นกอล์ฟ ลองตัวอย่างบางส่วน

ตัวระบุที่ถูกต้องสามารถเริ่มต้นด้วยอย่างใดอย่างหนึ่งUnicodeLetter, $, หรือ_ \ UnicodeEscapeSequenceตัวอักษร unicode เป็นตัวละครจากหมวดหมู่เหล่านี้ ( ดูหมวดหมู่ทั้งหมด ):

  • ตัวอักษรตัวพิมพ์ใหญ่ (Lu)
  • อักษรตัวพิมพ์เล็ก (Ll)
  • จดหมายชื่อตัวอักษร (Lt)
  • ตัวดัดแปลง (Lm)
  • จดหมายอื่น ๆ (Lo)
  • หมายเลขตัวอักษร (Nl)

นี้บัญชีเพียงอย่างเดียวสำหรับความเป็นไปได้บางบ้า - ตัวอย่างการใช้งาน หากไม่สามารถใช้งานได้ในทุกเบราว์เซอร์เรียกว่าเป็นข้อผิดพลาดทำให้เกิดข้อผิดพลาด

var  = "something";
var ĦĔĽĻŎ = "hello";
var 〱〱〱〱 = "less than? wtf";
var जावास्क्रिप्ट = "javascript"; // ok that's JavaScript in hindi
var KingGeorge = "Roman numerals, awesome!";

1
คุณกรุณาคัดลอกบรรทัดตัวอย่างไปยังหน้ารหัส Rosettaซึ่งตอนนี้ไม่มีตัวอย่าง JavaScript
วอลเตอร์ Tross

73

[a-zA-Z_$][0-9a-zA-Z_$]*โดยทั่วไปในรูปแบบการแสดงออกปกติ: กล่าวอีกนัยหนึ่งอักขระตัวแรกอาจเป็นตัวอักษรหรือ _ หรือ $ และอักขระอื่น ๆ อาจเป็นตัวอักษรหรือ _ หรือ $ หรือตัวเลขก็ได้

หมายเหตุ:ในขณะที่คำตอบอื่น ๆ ชี้ให้เห็นว่าคุณสามารถใช้อักขระ Unicode ในตัวระบุ JavaScript คำถามที่แท้จริงคือ "ฉันควรใช้อักขระใดสำหรับชื่อของไลบรารีส่วนขยายเช่น jQuery" นี่คือคำตอบสำหรับคำถามนั้น คุณสามารถใช้อักขระ Unicode ในตัวระบุได้ แต่อย่าทำ การเข้ารหัสจะทำให้เมาตลอดเวลา รักษาตัวระบุสาธารณะของคุณในช่วง 32-126 ASCII ที่ปลอดภัย


71
ฉันอาจจะลงมือฆ่าผู้ร่วมพัฒนาที่ใช้อักขระ Unicode ในชื่อป้ายกำกับของเขา / ถ้อยคำแดกดันแทบ
Erik Reppen

12
romkyns ฉันไม่คิดว่า "ชื่อตัวระบุอักขระ Unicode" จะรวมอยู่ใน "JavaScript: The Good Parts" และเช่นนี้ฉันชอบที่จะเพิกเฉยต่อการมีอยู่ของพวกเขา อย่างไรก็ตามฉันได้เพิ่มคำปฏิเสธไปยังคำตอบของฉันเพื่อประโยชน์ของคุณ
Anthony Mills

11
เกี่ยวกับการเข้ารหัส: โปรดทำอักขระการใช้งานที่ไม่ใช่ ASCII อย่างน้อยในสายอักขระตัวอักษรของคุณ เราต้องกำจัดซอฟท์แวร์โง่ ๆ ที่ได้รับการเข้ารหัส "ทำให้เมาตลอดเวลา" มันเป็นความสุขเพียงแค่พิมพ์Console.WriteLine("привет")ใน C # และใช้งานได้จริง !
Roman Starkov

14
ดู, @Timwi, โดยเฉพาะอย่างยิ่งเมื่อคุณเขียนห้องสมุด (อย่างที่ Richard บอกว่าเขาเป็น), มันไม่ควรบังคับให้ผู้ใช้ของคุณเข้าสู่อึ Alt-blah หรือ copy'n'pasting นอกจากนี้สำหรับสิ่งของของคุณเองคุณอาจพอใจกับการจัดการกับสิ่งที่น่ารำคาญเมื่อคุณพบข้อผิดพลาดของเบราว์เซอร์หรือพร็อกซีเซิร์ฟเวอร์หรืออะไรก็ตาม แต่การทำให้ผู้ใช้ห้องสมุดของคุณจัดการกับสิ่งนั้น คำตอบที่ดีตอบ "ฉันควรทำอย่างไร" มากกว่าแค่รับมือกับคำถาม ใช่ฉันต้องการช่วยเหลือผู้คน ฉันจะไม่รวมข้อมูลที่ไร้ประโยชน์และข้อมูลที่เป็นอันตรายเว้นแต่ว่าฉันจะพูดว่า "โอ๋และอย่าทำเช่นนี้"
Anthony Mills

37
@Tchalvak สำหรับรหัสที่คุณใช้อยู่อาจเป็นเรื่องปกติโดยใช้Ʒเป็นชื่อไลบรารีหลักของคุณ (โอ้คุณคิดว่านั่นคือ 3 หรือไม่ขออภัยจริง ๆ แล้วมันคือ U + 01B7 ตัวพิมพ์ใหญ่ละติน Ezh! หรือว่าЗ, Cyrillic Capital Letter Ze?) ถ้าคุณจะเขียนห้องสมุดที่คนอื่นอาจจะใช้ แม้ว่ามันจะดีที่สุดในการติดกับ ASCII
Anthony Mills

18

ก่อน JavaScript 1.5: ^[a-zA-Z_$][0-9a-zA-Z_$]*$

ในภาษาอังกฤษ:ต้องเริ่มต้นด้วยเครื่องหมายดอลลาร์, ขีดล่างหรือหนึ่งตัวอักษรในตัวอักษร 26 ตัวอักษร, ตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก อักขระที่ตามมา (ถ้ามี) สามารถเป็นหนึ่งในหนึ่งในนั้นหรือหลักทศนิยม

JavaScript 1.5 และใหม่กว่า* :^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$

นี่เป็นเรื่องยากกว่าที่จะแสดงเป็นภาษาอังกฤษ แต่มันเป็นแนวคิดที่คล้ายกับไวยากรณ์ที่เก่ากว่าด้วยการเพิ่มตัวอักษรและตัวเลขที่ได้จากภาษาใด ๆ หลังจากตัวละครตัวแรกมีการอนุญาตให้ใช้อักขระที่มีเครื่องหมายขีดล่างเพิ่มเติม (รวมเรียกว่า“ ตัวเชื่อมต่อ”) และเครื่องหมายเพิ่มเติมที่รวมเครื่องหมาย (“ ตัวดัดแปลง”) (สัญลักษณ์สกุลเงินอื่น ๆ ไม่รวมอยู่ในชุดเสริมนี้)

JavaScript 1.5 และใหม่กว่าอนุญาตให้ใช้ Unicode escape sequences โดยที่ผลลัพธ์คืออักขระที่อนุญาตให้ใช้ในนิพจน์ทั่วไปด้านบน

ตัวระบุต้องไม่เป็นคำที่สงวนไว้ในปัจจุบันหรือคำที่ใช้สำหรับการใช้ในอนาคต

ไม่มีการ จำกัด การปฏิบัติเพื่อความยาวของตัวระบุเป็น (เบราว์เซอร์จะแตกต่างกัน แต่คุณจะมี 1,000 ตัวอักษรอย่างปลอดภัยและอาจมีขนาดของคำสั่งมากกว่านั้น)

เชื่อมโยงไปยังหมวดหมู่ตัวอักษร:

  • ตัวอักษร: Lu , Ll , Lt , Lm , Lo , Nl
    (รวมอยู่ใน regex ข้างต้นเป็น“ L”)
  • เครื่องหมายรวม (“ ตัวดัดแปลง”): Mn , Mc
  • ตัวเลข: Nd
  • การเชื่อมต่อ: ชิ้น

* nb Perl นี้มีจุดประสงค์เพื่ออธิบายไวยากรณ์เท่านั้น - มันจะไม่ทำงานใน JavaScript ซึ่งยังไม่รวมถึงการสนับสนุนคุณสมบัติ Unicode (มีแพ็คเกจของบุคคลที่สามที่อ้างว่าเพิ่มการสนับสนุนดังกล่าว)


ฉันไม่สามารถทำให้ regex นี้ใช้งานได้จริง "test".match(/^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/) === nullแม้ว่า "test" เป็นชื่อตัวแปร JS ที่ถูกต้อง
David Murdoch

ขออภัย JavaScript ไม่รองรับ regex นี้ ฉันได้เพิ่มบันทึกเพื่อชี้แจง
danorton

5
ควรสังเกตว่า regex ที่สองของคุณมีผลบวกปลอม อักขระ Unicode เพิ่มเติม (เช่นU + 2F800 CJK Compatibility Ideographซึ่งแสดงอยู่ในหมวดหมู่ [Lo]) ไม่ได้รับอนุญาตในชื่อตัวระบุเนื่องจาก JavaScript ตีความว่าเป็นครึ่งตัวแทนสองส่วน (เช่น\uD87E\uDC00) ซึ่งไม่ตรงกับ Unicode ที่อนุญาตใด ๆ ประเภท อย่างไรก็ตาม regex ของคุณจะอนุญาตให้ใช้อักขระดังกล่าว นอกจากนี้ U + 200C และ U + 200D ก็หายไปเช่นกัน
Mathias Bynens

1
ES6 อย่างเป็นทางการกำหนดตัวระบุที่ถูกต้องโดยใช้คลาสตัวอักษรที่มีความหมายอย่างชัดเจนสำหรับวัตถุประสงค์นี้ (ใช้ใน progamming) - ไม่แน่ใจว่านี่เป็นความจริงก่อนหน้านี้ - หมายถึงคุณสามารถทำให้ regex นี้อ่านง่ายขึ้นเล็กน้อย อย่างน้อยก็น่าจะเป็นอย่างนั้นถ้ามันไม่ได้เป็นเพราะความจริงที่ว่าตอนนี้ Unicode escape นั้นถูกต้องในตัวระบุเช่นกัน! นี่เป็นไปตามข้อกำหนด ES6: (?: [\ p {ID_Start} \ $ _] | \\ u (?: [\ dA-Fa-f] {4} | \ {[\ dA-Fa-f ] + \})) ([\ P {ID_Continue} \ _ $ \ u200C \ u200D] | \\ ท่าน (: [\ dA-Fa-F] {4} | \ {[\ dA-Fa-F] + \})) *
เซมิโคลอน

14

ที่จริงแล้ว ECMAScript พูดในหน้า 15: ว่าตัวระบุอาจเริ่มต้นด้วย $, ขีดล่างหรือ UnicodeLetter และจากนั้นมันจะไป (ด้านล่างว่า) เพื่อระบุว่า UnicodeLetter สามารถเป็นตัวละครใด ๆ จากหมวด Unicode Lo, Ll , Lu, Lt, Lm และ Nl และเมื่อคุณค้นหาหมวดหมู่เหล่านั้นคุณจะเห็นว่าสิ่งนี้เปิดโอกาสให้คุณได้มากกว่าตัวอักษรละติน เพียงค้นหา "unicode catagories" ใน google และคุณสามารถค้นหาได้


ข้อผิดพลาดในการเชื่อมต่อและ 404 ทั้งหมดที่ฉันได้รับสำหรับผลลัพธ์ที่เกี่ยวข้องทุกครั้งเมื่อ googling สำหรับ ("หมวดหมู่ unicode") ... :(
Calmarius

13

ตัวแปร Javascript

คุณสามารถเริ่มต้นตัวแปรด้วยตัวอักษร$หรือ_ตัวอักษรใด ๆ ตราบใดที่มันไม่ได้ขึ้นต้นด้วยตัวเลขคุณสามารถรวมตัวเลขได้เช่นกัน

ราคาเริ่มต้น: [a-z], $, _

ประกอบด้วย: [a-z], [0-9], $, _

jQuery

คุณสามารถใช้_สำหรับห้องสมุดของคุณเพื่อให้ jQuery ยืนเคียงข้างกัน อย่างไรก็ตามมีการกำหนดค่าที่คุณสามารถตั้งค่าเพื่อไม่ให้ jQuery ใช้งาน$ได้ jQueryมันจะใช้แทน หากต้องการทำสิ่งนี้ให้ตั้งค่าเพียง:

jQuery.noConflict();

หน้านี้อธิบายวิธีการทำเช่นนี้


มันถูกต้องอย่างแน่นอน แต่ฉันให้คำตอบกับแอนโทนี่ที่ตอบ. 02123413124 มิลลิวินาทีก่อนหน้าคุณ ขอโทษ
Richard Clayton

8
@ Richard: ไม่มันไม่ถูกต้องอย่างแน่นอน ดูคำตอบของ @Yuvalik และ @ Anurag
Tim Down

@EndangeredMassa ทำไมต้องใช้ตัวแปร "_name" ทำไมไม่เพียงแค่ชื่อ
Tomasz Waszczyk

9

คำตอบที่ยอมรับจะแยกแยะตัวระบุที่ถูกต้องได้มากเท่าที่ฉันเห็น นี่คือนิพจน์ทั่วไปที่ฉันรวบรวมไว้ซึ่งควรทำตามข้อมูลจำเพาะ (ดูบทที่ 7.6 เกี่ยวกับตัวระบุ) สร้างขึ้นโดยใช้ RegexBuddy และคุณจะพบการส่งออกของคำอธิบายที่http://samples.geekality.net/js-identifiers

^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\u200C\u200D]*+$

นอกจากนี้ชื่อไม่สามารถเป็นหนึ่งในคำสงวนต่อไปนี้

break, do, instanceof, typeof, case, else, ใหม่, var, catch, ในที่สุด, return, void, ดำเนินการต่อ, สำหรับ, switch, ในขณะที่ debugger, ฟังก์ชั่น, สิ่งนี้พร้อมกับค่าเริ่มต้น, ถ้า, ลอง, คลาส, enum, ขยาย, super, const, การส่งออก, นำเข้า, นำไปปฏิบัติ, ให้, ส่วนตัว, สาธารณะ, ให้ผลผลิต, ส่วนต่อประสาน, หีบห่อที่ได้รับการป้องกัน, คงที่, ว่างเปล่า, เป็นจริง, เท็จ


regex นี้ไม่ใช่ JS regex ที่ถูกต้อง ^[$_\p{L}][$_\p{L}\p{Mn}\p{Mc}\p{Nd}\p{Pc}\u200C\u200D]*$ฉันคิดว่าคุณหมายถึง: ตอนนี้แม้จะมีการแก้ไขฉันไม่สามารถทำให้ regex นี้ใช้งานได้จริง "test".match(/^[\p{L}\p{Nl}$_][\p{L}\p{Nl}$\p{Mn}\p{Mc}\p{Nd}\p{Pc}]*$/) === nullแม้ว่า "test" เป็นชื่อตัวแปร JS ที่ถูกต้อง
David Murdoch

ไม่ฉันค่อนข้างแน่ใจว่าฉันหมายถึงสิ่งที่ฉันเขียน :) คำถามตามที่ฉันเข้าใจเพิ่งถามว่าชื่อฟังก์ชันจาวาสคริปต์ที่ถูกต้องคืออะไร ฉันสร้างมันใน RegexBuddy และฉันใช้มันใน PHP ในหน้าตัวอย่างที่ฉันลิงก์ไป ใช้งานได้ดีและtestเป็นที่ยอมรับเช่นกัน
Svish

3
@DavidMurdoch ฉันได้เขียนนิพจน์ปกติที่เข้ากันได้กับ JavaScript 11,335 ตัวที่สามารถใช้ตรวจสอบตัวระบุ (ชื่อตัวแปร aka) ดูคำตอบของฉัน
Mathias Bynens

3
@Svish ควรสังเกตว่า regex ของคุณมีผลบวกปลอม อักขระ Unicode เพิ่มเติม (เช่นU + 2F800 CJK Compatibility Ideographซึ่งแสดงอยู่ในหมวดหมู่ [Lo]) ไม่ได้รับอนุญาตในชื่อตัวระบุเนื่องจาก JavaScript ตีความว่าเป็นครึ่งตัวแทนสองส่วน (เช่น\uD87E\uDC00) ซึ่งไม่ตรงกับ Unicode ที่อนุญาตใด ๆ ประเภท อย่างไรก็ตาม regex ของคุณจะอนุญาตให้ใช้อักขระดังกล่าว
Mathias Bynens

2
@Svish ดีใช่โดยการเขียนออกมาช่วงที่ตัวเองเหมือนผม :) ทราบว่า regex ของคุณยังไม่บัญชีสำหรับ, , , และกรณีขอบ evalargumentsNaNInfinityundefined
Mathias Bynens

6

ตัวแปร Javascript สามารถมีตัวอักษรตัวเลขเครื่องหมายดอลลาร์ ($) และขีดล่าง (_) พวกเขาไม่สามารถเริ่มด้วยตัวเลข

โดยปกติแล้วไลบรารีจะใช้$และ_เป็นทางลัดสำหรับฟังก์ชั่นที่คุณจะใช้งานได้ทุกที่ แม้ว่าชื่อ$หรือชื่อ_นั้นไม่มีความหมาย แต่ก็มีประโยชน์สำหรับความสั้นและเนื่องจากคุณจะใช้ฟังก์ชั่นทุกที่ที่คุณคาดว่าจะรู้ว่าพวกเขาหมายถึงอะไร

ถ้าห้องสมุดของคุณไม่ได้ประกอบด้วยในการรับฟังก์ชั่นเดียวถูกนำมาใช้ทุกที่ผมขอแนะนำให้คุณใช้ชื่อที่มีความหมายมากขึ้นกับผู้ที่จะช่วยให้คุณและคนอื่น ๆ เข้าใจสิ่งที่รหัสของคุณจะทำโดยไม่จำเป็นต้องสูญเสียแหล่งที่มารหัสความอ่อนโยน

ตัวอย่างเช่นคุณสามารถดูที่ห้องสมุดDateJS ที่ยอดเยี่ยมและที่น้ำตาล syntatic จะช่วยให้โดยไม่ต้องใช้สัญลักษณ์หรือตัวแปรที่มีชื่อสั้น ๆ

ก่อนอื่นคุณควรให้โค้ดของคุณใช้งานได้จริงและหลังจากพยายามทำให้มันสวย


4

ในกรณีที่ไม่จำเป็นต้องมีการแสดงออกปกติจะดีกว่าหรือไม่ที่จะขอให้เบราว์เซอร์ตัดสินใจใช้eval?

function isValidVarName( name ) {
    try {
        // Update, previoulsy it was
        // eval('(function() { var ' + name + '; })()');
        Function('var ' + name);
    } catch( e ) {
        return false;
    }
    return true;
}

isValidVarName('my_var');     // true
isValidVarName('1');          // false

6
ไม่มันจะไม่ xss = alert("I'm in your vars executin mah scrip's");;;;;เช่นไม่ใช่ชื่อตัวแปรจาวาสคริปต์ที่ถูกต้อง
1j01

6
xss;alert("try again");
1j01

1
มันเป็นความคิดที่ฉลาดแม้จะมีช่องโหว่ในการโจมตี XSS
แปรงสีฟัน

@ 1j01 วิธีการแทนที่nameด้วย(typeof name === "string")? name.replace(/\(|\)/,"") : "_noXSS" )? ถ้าเป็นสตริงมันจะแทนที่วงเล็บ (ไม่ได้รับอนุญาตแน่นอนในตัวแปร) ดังนั้นฉันคิดว่าการดำเนินการใด ๆ จะเป็นไปไม่ได้เกือบ
royhowie

2
ถ้าอย่างนั้นก็isValidVarName('aler(t')กลายเป็นจริง และisValidVarName('_;;;')ยังคงความเป็นจริง แต่คุณสามารถตรวจสอบที่จุดเริ่มต้นถ้ามันตรงกับสิ่งที่ชอบ/[;,\(\)]/แต่แล้วคุณยังสามารถดำเนินการ_=location="#!?"เพื่อให้คุณเพิ่ม=ในรายการ แต่คุณยังสามารถดำเนินการ'_\ndelete foo'(ซึ่งผ่านการทดสอบเป็นชื่อตัวแปรที่ถูกต้อง) ดังนั้นคุณต้องแยก\ns และ\rs และอาจ ขึ้นบรรทัดใหม่บาง Unicode? แต่ `$ 'ไม่ใช่ตัวระบุที่ถูกต้องดังนั้นคุณต้องยกเว้นพื้นที่ว่างทั้งหมด ... มันเป็นการต่อสู้ที่พ่ายแพ้ ฉันคิดว่าเท่าที่ฉันจะสามารถต่อสู้กับตัวเองด้วยif(/[;,\(\)=\s]/.exec(name))return!1
1j01

1

นี่คือคำแนะนำด่วนสำหรับการสร้างชื่อตัวแปร หากคุณต้องการให้ตัวแปรไม่ขัดแย้งเมื่อใช้ใน FireFox ห้ามใช้ชื่อตัวแปร " _content " เนื่องจากชื่อตัวแปรนี้กำลังถูกใช้งานโดยเบราว์เซอร์ ฉันพบสิ่งนี้ยากและต้องเปลี่ยนสถานที่ทั้งหมดที่ฉันใช้ตัวแปร "_content" ในแอปพลิเคชัน JavaScript ขนาดใหญ่


คุณสามารถพิสูจน์ได้ด้วยซอร์สโค้ดบางตัวที่ล้มเหลว? ดูเหมือนจะไม่ทำอะไรเลยใน Firefox
แปรงสีฟัน

นี่คือ jsfiddle ว่าการแจ้งเตือนเมื่อตัวแปร "_content" ไม่ได้ "ไม่ได้กำหนด" และเมื่อ "_content" ถูกกำหนดโดย FireFox มันถูกตั้งค่าให้เท่ากับ "window.content" jsfiddle.net/R2qvt/3
DanBrianWhite

1

ฉันใช้ความคิดของ Anas Nakawa และปรับปรุงมัน ประการแรกไม่มีเหตุผลที่จะเรียกใช้ฟังก์ชันที่ประกาศ เราต้องการทราบว่ามันแยกวิเคราะห์อย่างถูกต้องไม่ว่ารหัสทำงาน ประการที่สองวัตถุที่แท้จริงเป็นบริบทที่ดีกว่าสำหรับจุดประสงค์ของเรากว่าvar XXXที่มันยากที่จะแยกออกจาก

    function isValidVarName( name ) {
    try {
        return name.indexOf('}') === -1 && eval('(function() { a = {' + name + ':1}; a.' + name + '; var ' + name + '; }); true');
    } catch( e ) {
        return false;
    }
    return true;
}

// so we can see the test code
var _eval = eval;
window.eval = function(s) {
    console.log(s);
    return _eval(s);
}

console.log(isValidVarName('name'));
console.log(isValidVarName('$name'));
console.log(isValidVarName('not a name'));
console.log(isValidVarName('a:2,b'));
console.log(isValidVarName('"a string"'));

console.log(isValidVarName('xss = alert("I\'m in your vars executin mah scrip\'s");;;;;'));
console.log(isValidVarName('_;;;'));
console.log(isValidVarName('_=location="#!?"'));

console.log(isValidVarName('ᾩ'));
console.log(isValidVarName('ĦĔĽĻŎ'));
console.log(isValidVarName('〱〱〱〱'));
console.log(isValidVarName('जावास्क्रिप्ट'));
console.log(isValidVarName('KingGeorgeⅦ'));
console.log(isValidVarName('}; }); alert("I\'m in your vars executin\' mah scripts"); true; // yeah, super valid'));
console.log(isValidVarName('if'));

1
อย่าแม้แต่จะลอง isValidVarName('}; }); alert("I\'m in your vars executin\' mah scripts"); true; // yeah, super valid');
1j01

1
@ 1j01 อ๊ะฉันลืมรหัสความคิดเห็น ฉันหวังว่าการไม่สมดุลของวงเล็บเพียงอย่างเดียวอาจทำให้โค้ดไม่ทำงาน การตรวจสอบง่าย ๆ}ควรตัดสิ่งนี้ออก
cleong

isValidVarName("delete") === true
1j01

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.