วิธีตรวจสอบตัวแปรที่ไม่ได้กำหนดใน JavaScript


913

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

alert( x );

ฉันจะจับข้อผิดพลาดนี้ได้อย่างไร



5
ดูเหมือนว่านี่คือคุณปู่: stackoverflow.com/questions/1485840/… stackoverflow.com/questions/2647867// - แกรมที่ดีอาจเป็นเช่นนี้: stackoverflow.com/questions/27509/…
สุ่ม

1
นี่ไม่ใช่ของซ้ำซ้อนที่ทำเครื่องหมายไว้ ความละเอียดของตัวแปรและการแก้ไขคุณสมบัติของวัตถุนั้นแตกต่างกันมาก การทำสำเนาที่ดีกว่าคือการตรวจสอบว่ามีตัวแปรอยู่ในจาวาสคริปต์หรือไม่? .
RobG

ข้อผิดพลาดของคุณเกิดจากตัวแปรที่ไม่ได้รับการประกาศ คำตอบส่วนใหญ่มุ่งเน้นไปที่การมอบหมาย ดูคำตอบของฉันมากขึ้น นอกจากนี้หลายคนระบุว่าไม่ถูกต้องว่าเป็นโมฆะและไม่ได้กำหนดเป็นวัตถุใน JavaScript มันเป็นสิ่งพื้นฐานไม่ใช่วัตถุ ...
JBallin

คำตอบ:


1690

ใน JavaScript nullเป็นวัตถุ มีค่าอีกอย่างสำหรับสิ่งที่ไม่มีอยู่, undefined. DOM ส่งคืนnullเกือบทุกกรณีที่ล้มเหลวในการค้นหาโครงสร้างบางอย่างในเอกสาร แต่ใน JavaScript เองundefinedคือค่าที่ใช้

ประการที่สองไม่ไม่เทียบเท่าโดยตรง หากคุณต้องการตรวจสอบเป็นพิเศษให้nullทำ:

if (yourvar === null) // Does not execute if yourvar is `undefined`

หากคุณต้องการตรวจสอบว่ามีตัวแปรอยู่หรือไม่นั้นสามารถทำได้ด้วยtry/ catchเนื่องจากtypeofจะจัดการกับตัวแปรที่ไม่ได้ประกาศและตัวแปรที่ประกาศด้วยค่าundefinedเท่ากับ

แต่เพื่อตรวจสอบว่ามีการประกาศตัวแปรหรือไม่และundefined:

if (yourvar !== undefined) // Any scope

ก่อนหน้านี้มีความจำเป็นต้องใช้typeofโอเปอเรเตอร์เพื่อตรวจสอบการไม่ได้กำหนดอย่างปลอดภัยเพราะมันเป็นไปได้ที่จะกำหนดใหม่undefinedเหมือนตัวแปร วิธีเก่า ๆ มีลักษณะเช่นนี้:

if (typeof yourvar !== 'undefined') // Any scope

ปัญหาของundefinedการกำหนดใหม่ได้รับการแก้ไขใน ECMAScript 5 ซึ่งเปิดตัวในปี 2009 ตอนนี้คุณสามารถใช้งานได้อย่างปลอดภัย===และ!==ทดสอบundefinedโดยไม่ต้องใช้typeofเนื่องจากundefinedได้อ่านอย่างเดียวมาระยะหนึ่งแล้ว

หากคุณต้องการทราบว่าสมาชิกมีอิสระ แต่ไม่สนใจว่าคุณค่าคืออะไร:

if ('membername' in object) // With inheritance
if (object.hasOwnProperty('membername')) // Without inheritance

หากคุณต้องการทราบว่าตัวแปรเป็นจริงหรือไม่ :

if (yourvar)

แหล่ง


71
ไม่ได้กำหนดไม่ใช่คำสงวน; คุณ (หรือรหัสของคนอื่น) สามารถทำ "undefined = 3" และนั่นจะทำให้การทดสอบของคุณสองครั้ง
464 Jason S

6
"ถ้าคุณรู้ว่าตัวแปรนั้นมีอยู่ แต่ไม่รู้ว่ามีค่าใดถูกเก็บอยู่หรือไม่" - ฮะ!
464 Jason S

36
ฉันคิดว่าเขาหมายถึงตัวแปรที่ประกาศว่าไม่ได้รับมอบหมาย เช่น: var foo; // foo มีอยู่ แต่ไม่มีค่า
Wally Lawless

3
อืม ... ฉันเพิ่งสังเกตเห็นลิงก์ "แหล่งที่มา": โพสต์ทั้งหมดนี้เป็นคำพูดโดยตรงจากรายชื่อผู้รับจดหมาย & ควรได้รับการแก้ไขเพื่อให้ชัดเจนยิ่งขึ้นเนื่องจากผู้เขียนต้นฉบับไม่สามารถชี้แจงได้
464 Jason S

11
"ใน JavaScript null เป็นวัตถุ" นั่นไม่จริงจริงและอาจเป็นสาเหตุของการเข้าใจผิดนี้คือtypeofโอเปอเรเตอร์ ( typeof null == 'object') nullค่าเป็นค่าดั้งเดิมซึ่งเป็นค่าเดียวของชนิด Null
CMS

347

วิธีเดียวที่จะทดสอบว่าตัวแปรคือundefinedทำสิ่งต่อไปนี้อย่างแท้จริงหรือไม่ โปรดจำไว้ว่าไม่ได้กำหนดเป็นวัตถุใน JavaScript

if (typeof someVar === 'undefined') {
  // Your variable is undefined
}

โซลูชันอื่น ๆ บางรายการในชุดข้อความนี้จะทำให้คุณเชื่อว่าตัวแปรไม่ได้ถูกกำหนดแม้ว่าจะได้รับการกำหนด (ด้วยค่า NULL หรือ 0 เป็นต้น)


18
เนื่องจากคำถามไม่ได้ถูกยกเลิกการกำหนดที่นี่ควรเป็นประเภทของ someVar! == 'undefined' ใช่ไหม
eomeroff

1
จริง ๆ แล้วฉันไม่คิดว่าสิ่งที่ไม่ถูกค้นพบนั้นเป็นวัตถุให้ตรวจสอบเอกสารก่อนdeveloper.mozilla.org/en-US/docs/Web/JavaScript/Data_structures
Nicramus

2
ReferenceErrorการทดสอบเท่านั้นซึ่งไม่สามารถผลิต
Nostalg.io

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

1
ตอนนี้มันไม่ถูกต้องในแง่ของมันเป็นวิธีเดียว undefinedได้รับการอ่านอย่างเดียวตั้งแต่ ES5 คุณสามารถทดสอบการใช้งานไม่ได้กำหนดหรือใช้จดชวเลขเช่นนี้if (x === undefined) {...} if (x === void 0)
Stephen M Irving

66

ในทางเทคนิคแล้วการแก้ปัญหาที่เหมาะสมคือ (ฉันเชื่อ):

typeof x === "undefined"

บางครั้งคุณอาจขี้เกียจและใช้งานได้

x == null

แต่นั่นจะอนุญาตให้ทั้งตัวแปรที่ไม่ได้นิยาม x และตัวแปร x ที่มีค่า null จะส่งกลับค่าจริง


1
ถ้าคุณพิมพ์var x;แล้วtypeof x;คุณจะได้รับ"undefined"เหมือนว่าคุณทำtypeof lakjdflkdsjflsj;
Muhammad Umer

ดังนั้นจึงไม่มีวิธีการตรวจสอบตัวแปรที่ไม่ได้กำหนด แต่ประกาศหรือไม่?
มูฮัมหมัดอูเมอ

1
ฉันไม่คิดอย่างนั้น ฉันไม่แน่ใจว่าทำไมคุณต้องการ
Jason S

ujndefined ไม่ควรอยู่ระหว่าง apices
LowFieldTheory

คุณหมายถึงอะไรโดย apices
Jason S

19

เวอร์ชั่นย่อที่ง่ายยิ่งขึ้นและมากขึ้นคือ:

if (!x) {
   //Undefined
}

หรือ

if (typeof x !== "undefined") {
    //Do something since x is defined.
}

26
รหัสชิ้นแรกอาจไม่ถูกต้องหาก x ถูกตั้งค่าจากการเรียกใช้ฟังก์ชัน ชอบ x = A (); ถ้า A ไม่คืนค่าใด ๆ มันจะคืนค่า "undefined" โดยค่าเริ่มต้น การทำ! x จะเป็นจริงซึ่งจะถูกต้องตามหลักเหตุผล อย่างไรก็ตามหาก A () ส่งคืน 0 ดังนั้น! x ควรเป็นเท็จเป็น x = 0 อย่างไรก็ตามใน JS,! 0 ก็เป็นจริงเช่นกัน
Rajat

รหัสที่สองสามารถย่อให้เหลือน้อยกว่า: ถ้า (! typeof (XX)) {... } else {... }
Alejandro Silva

2
@AlejandroSilva ขออภัยในความล่าช้า นั่นจะไม่ทำงานเนื่องจาก typeof ส่งคืนสตริงดังนั้นมันจะส่งกลับ 'undefined' สำหรับตัวแปรที่ไม่ได้กำหนดซึ่งจะประเมินเป็น TRUE ดังนั้นจึงนำไปสู่การบวกเท็จของ var ที่กำหนด
Dmitri Farkov

5
โปรดกำจัดตัวอย่างแรกมันไม่ดีเลย
Juan Mendes

1
ความคิดเห็นอื่น ๆ ชี้ให้เห็นว่าตัวอย่างแรกนั้นไม่ดี แต่ไม่ชัดเจนว่าทำไม ดังนั้นสำหรับโคเดอร์ใหม่ใด ๆ !! x ไม่ได้ทดสอบว่ามีการกำหนด x แต่ไม่ว่าจะเป็นความจริงหรือไม่ สตริง, บูลีนจริงและตัวเลขบวกล้วนเป็นความจริงทั้งหมด (และฉันอาจลืมบางสิ่ง), แต่ค่าอื่น ๆ ที่อาจเป็นไปได้เช่น 0, บูลีนเท็จ, และสตริงว่างเปล่าไม่ใช่ความจริง ตัวอย่างแรกสามารถใช้ได้กับกรณีการใช้งานเฉพาะ (เช่นการทดสอบสตริงหากคุณสามารถใช้งานว่างได้เหมือนกับที่ไม่ได้กำหนด) แต่เนื่องจากหลาย ๆ กรณีที่มันไม่สามารถทำได้จึงไม่ควรพิจารณาวิธีการตรวจสอบเริ่มต้น
cfc

16

ฉันมักจะทำ:

function doSomething(variable)
{
    var undef;

    if(variable === undef)
    {
         alert('Hey moron, define this bad boy.');
    }
}

9
ลองพิจารณาเปลี่ยน "==" เป็น "===" หากคุณโทรหา doSomething (null) คุณจะได้รับการแจ้งเตือนด้วย เว้นแต่ว่าเป็นสิ่งที่คุณต้องการ
464 Jason S

อ๋อ คุณต้องตัดสินใจว่าคุณต้องการเทียบเท่าหรือเท่ากับ ทั้งสองกรณีสามารถใช้งานได้
Joe

1
เพียงแค่ตรวจสอบเช่นนี้ -> if (typeof variableName! == 'undefined') {alert (variableName);}
Muhammad Sadiq

นี้ไม่มีประโยชน์เนื่องจากคุณจะไม่สามารถส่งค่า var ที่ไม่ได้กำหนดไปยังฟังก์ชันได้
avalanche1

2
แน่นอนว่าคุณสามารถ ลองเรียกใช้ฟังก์ชันโดยไม่มีการโต้แย้ง
โจ

3

คุณยังสามารถใช้ตัวดำเนินการเงื่อนไขประกอบไปด้วย:

var a = "hallo world";
var a = !a ? document.write("i dont know 'a'") : document.write("a = " + a);

//var a = "hallo world";
var a = !a ? document.write("i dont know 'a'") : document.write("a = " + a);


เกิดอะไรขึ้นถ้าvar a = false;? คุณควรตรวจสอบว่าถ้าa===undefinedแทน
Iter Ator

1
คำถาม: ตรวจสอบตัวแปรที่ไม่ได้กำหนด ..... นี่คือตัวแปรที่ไม่ได้กำหนด: var x; การดำเนินการด้านบนจะทำให้เกิดข้อผิดพลาด
Muhammad Umer

"ถ้า a = false แสดงว่า" ฉันไม่รู้ 'a' "" - นั่นคือปัญหาคำถามคือการทดสอบว่ามันถูกกำหนดหรือไม่ไม่ใช่ว่าจริงหรือไม่ หาก a ถูกกำหนดเป็น false ดังนั้น a จะไม่ถูกกำหนด นี่จะส่งคืนผลลัพธ์ที่ผิดในกรณีนั้น ดูความคิดเห็นของฉันในstackoverflow.com/a/858270/2055492เพื่อดูรายละเอียดเพิ่มเติมว่าทำไมวิธีการนี้ใช้ไม่ได้
cfc

ไม่เพียง แต่จะ!aทดสอบความเป็นจริงundefinedก็ยังทดสอบจริงสำหรับ0และและnull falseสิ่งนี้ไม่ถูกต้องมากและควรลบออก
Stephen M Irving

2

ฉันมักจะใช้วิธีที่ง่ายที่สุด:

var variable;
if (variable === undefined){
    console.log('Variable is undefined');
} else {
    console.log('Variable is defined');
}

แก้ไข:

หากไม่มีการเริ่มต้นตัวแปรข้อยกเว้นจะถูกโยน "Uncaught ReferenceError: ตัวแปรไม่ได้ถูกกำหนด ... "


2
Uncaught ReferenceError: variable is not defined
มูฮัมหมัดอูเมอร์

@ MuhammadUmer ผิดพลาด! จะถูกกำหนดโดยvariable var variable;และตัวอย่างนี้จะแทนที่variableในขอบเขตท้องถิ่น มันสามารถทำลายตรรกะที่คาดว่าจะเข้าถึงการปิดหรือตัวแปรทั่วโลก เช่น:var variable = 1; function test() { var variable; if (variable === undefined){ console.log('Variable is undefined'); } else { console.log('Variable is defined: ' + variable); } } test(); // Variable is undefined
ЕвгенийСавичев

2

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

if (window.x) {
    alert('x exists and is truthy');
} else {
    alert('x does not exist, or exists and is falsy');
}

นี่ไม่ได้แก้คำถามเดิมเลยและไม่เกี่ยวข้องทั้งหมด ผู้โพสต์ไม่ได้ถามวิธีการทดสอบว่ามีอะไรจริงหรือเท็จเขาถามว่าจะทดสอบundefinedอย่างไร สิ่งนี้จะไม่ทำเช่นนั้น
Stephen M Irving

2

ข้อผิดพลาดกำลังบอกคุณว่าxไม่มีอยู่จริง! ยังไม่ได้ประกาศซึ่งแตกต่างจากการกำหนดค่า

var x; // declaration
x = 2; // assignment

หากคุณประกาศxคุณจะไม่ได้รับข้อผิดพลาด คุณจะได้รับการแจ้งเตือนที่ระบุว่าundefinedเนื่องจากxมีอยู่ / ได้รับการประกาศแล้วแต่ยังไม่ได้รับการกำหนดค่า

ในการตรวจสอบว่ามีการประกาศตัวแปรหรือไม่คุณสามารถใช้typeofวิธีอื่นในการตรวจสอบว่ามีตัวแปรอยู่หรือไม่ที่จะทำให้เกิดข้อผิดพลาดเดียวกับที่คุณได้รับในตอนแรก

if(typeof x  !==  "undefined") {
    alert(x);
}

xนี้คือการตรวจสอบชนิดของค่าที่เก็บไว้ใน มันจะกลับมาundefinedเมื่อxยังไม่ได้รับการประกาศหรือถ้ามันได้รับการประกาศและยังไม่ได้รับมอบหมาย


ไม่ได้กำหนดได้ถูกอ่านอย่างเดียวตั้งแต่ ES5 (2009 รีลีส) และคุณไม่ต้องการtypeofผู้ประกอบการอีกต่อไป
Stephen M Irving

2

voidผลตอบแทนที่ผู้ประกอบการundefinedสำหรับการโต้แย้งใด ๆ / การแสดงออกผ่านไป เพื่อให้คุณสามารถทดสอบกับผลลัพธ์ (อันที่จริงตัวแปลงบางตัวเปลี่ยนรหัสของคุณจากundefinedเป็นvoid 0เพื่อบันทึกอักขระสองสามตัว)

ตัวอย่างเช่น:

void 0
// undefined

if (variable === void 0) {
    // variable is undefined
}

Ding ding! นี่คือคำตอบที่ถูกต้อง ความอัปยศมันคือทั้งหมดที่ด้านล่าง ทุกคนต่างก็ยังคงแขวนใช้typeofและคิดว่าundefinedสามารถกำหนดใหม่ซึ่งไม่สามารถทำได้ประมาณหนึ่งทศวรรษ
Stephen M Irving

สิ่งนี้ยังปลอดภัยก่อน ES5 เพราะย้อนกลับไปแล้วแม้ว่าคุณจะได้รับมอบหมายใหม่undefinedเพราะพระเจ้าเท่านั้นที่รู้เหตุผลว่าการใช้void 0จะกลับมาundefinedโดยไม่คำนึงถึง
Stephen M Irving

1

เราสามารถตรวจสอบได้undefinedดังนี้

var x; 

if (x === undefined) {
    alert("x is undefined");
} else {
     alert("x is defined");
}

1

ทำสิ่งที่ต้องการด้านล่าง:

function isNotDefined(value) {
  return typeof value === "undefined";
}

และเรียกว่าชอบ:

isNotDefined(undefined); //return true
isNotDefined('Alireza'); //return false

0

คำตอบที่ยอมรับนั้นถูกต้อง แค่ต้องการเพิ่มอีกหนึ่งตัวเลือก คุณยังสามารถใช้try ... catchบล็อกเพื่อจัดการสถานการณ์นี้ ตัวอย่างนอกลู่นอกทาง:

var a;
try {
    a = b + 1;  // throws ReferenceError if b is not defined
} 
catch (e) {
    a = 1;      // apply some default behavior in case of error
}
finally {
    a = a || 0; // normalize the result in any case
}

ระวังcatchบล็อกซึ่งค่อนข้างยุ่งเพราะมันสร้างขอบเขตระดับบล็อก และแน่นอนตัวอย่างนั้นง่ายมากในการตอบคำถามที่ถาม แต่ไม่ครอบคลุมถึงแนวปฏิบัติที่ดีที่สุดในการจัดการข้อผิดพลาด;)


0

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

ไม่ได้สร้างอินสแตนซ์ - var my_variable; -var my_variable = "";

function varExists(el) { 
  if ( typeof el !== "undefined" && typeof el.val() !== "undefined" ) { 
    return true; 
  } else { 
    return false; 
  } 
}

จากนั้นคุณสามารถใช้คำสั่งแบบมีเงื่อนไขเพื่อทดสอบว่าตัวแปรได้รับการกำหนดและอินสแตนซ์แบบนี้ ...

if ( varExists(variable_name) ) { // checks that it DOES exist } 

หรือเพื่อทดสอบว่ายังไม่ได้กำหนดและใช้งานอินสแตนซ์ ...

if( !varExists(variable_name) ) { // checks that it DOESN'T exist }

1
ทำไมไม่ส่งคืนคำกริยาของคุณทันที return typeof el !== "undefined" && typeof el.val() !== "undefined"
skubski
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.