อายุด้ายเก่า แต่มีวิธีการใหม่ ๆ isset()
ในการทำงานเทียบเท่า
ESNext (ด่าน 4 ธันวาคม 2562)
ไวยากรณ์ใหม่สองแบบช่วยให้เราสามารถใช้งานได้ง่ายขึ้นอย่างมากมายisset()
:
โปรดอ่านเอกสารและคำนึงถึงความเข้ากันได้ของเบราว์เซอร์
คำตอบก่อนหน้า
ดูคำอธิบายด้านล่าง หมายเหตุฉันใช้ไวยากรณ์ StandardJS
ตัวอย่างการใช้งาน
// IMPORTANT pass a function to our isset() that returns the value we're
// trying to test(ES6 arrow function)
isset(() => some) // false
// Defining objects
let some = { nested: { value: 'hello' } }
// More tests that never throw an error
isset(() => some) // true
isset(() => some.nested) // true
isset(() => some.nested.value) // true
isset(() => some.nested.deeper.value) // false
// Less compact but still viable except when trying to use `this` context
isset(function () { return some.nested.deeper.value }) // false
ฟังก์ชั่นคำตอบ
/**
* Checks to see if a value is set.
*
* @param {Function} accessor Function that returns our value
*/
function isset (accessor) {
try {
// Note we're seeing if the returned value of our function is not
// undefined
return typeof accessor() !== 'undefined'
} catch (e) {
// And we're able to catch the Error it would normally throw for
// referencing a property of undefined
return false
}
}
คำอธิบาย
PHP
โปรดทราบว่าใน PHP คุณสามารถอ้างอิงตัวแปรใด ๆ ที่ระดับความลึกใด ๆ - แม้จะพยายามเข้าถึง non-array เนื่องจาก array จะคืนค่าแบบง่าย ๆtrue
หรือfalse
:
// Referencing an undeclared variable
isset($some); // false
$some = 'hello';
// Declared but has no depth(not an array)
isset($some); // true
isset($some['nested']); // false
$some = ['nested' => 'hello'];
// Declared as an array but not with the depth we're testing for
isset($some['nested']); // true
isset($some['nested']['deeper']); // false
JS
ใน JavaScript เราไม่มีอิสระเราจะได้รับข้อผิดพลาดเสมอหากเราทำเช่นเดียวกันเพราะ JS พยายามเข้าถึงคุณค่าdeeper
ก่อนที่เราจะสามารถห่อในisset()
ฟังก์ชันของเราดังนั้น ...
// Common pitfall answer(ES6 arrow function)
const isset = (ref) => typeof ref !== 'undefined'
// Same as above
function isset (ref) { return typeof ref !== 'undefined' }
// Referencing an undeclared variable will throw an error, so no luck here
isset(some) // Error: some is not defined
// Defining a simple object with no properties - so we aren't defining
// the property `nested`
let some = {}
// Simple checking if we have a declared variable
isset(some) // true
// Now trying to see if we have a top level property, still valid
isset(some.nested) // false
// But here is where things fall apart: trying to access a deep property
// of a complex object; it will throw an error
isset(some.nested.deeper) // Error: Cannot read property 'deeper' of undefined
// ^^^^^^ undefined
ทางเลือกที่ล้มเหลวเพิ่มเติม:
// Any way we attempt to access the `deeper` property of `nested` will
// throw an error
some.nested.deeper.hasOwnProperty('value') // Error
// ^^^^^^ undefined
Object.hasOwnProperty('value', some.nested.deeper) // Error
// ^^^^^^ undefined
// Same goes for typeof
typeof some.nested.deeper !== 'undefined' // Error
// ^^^^^^ undefined
และทางเลือกการทำงานบางอย่างที่สามารถซ้ำซ้อนได้อย่างรวดเร็ว:
// Wrap everything in try...catch
try { isset(some.nested.deeper) } catch (e) {}
try { typeof some.nested.deeper !== 'undefined' } catch (e) {}
// Or by chaining all of the isset which can get long
isset(some) && isset(some.nested) && isset(some.nested.deeper) // false
// ^^^^^^ returns false so the next isset() is never run
ข้อสรุป
ทั้งหมดของคำตอบอื่น ๆ - แต่ส่วนใหญ่ทำงานได้ ...
- สมมติว่าคุณกำลังตรวจสอบเพื่อดูว่าตัวแปรไม่ได้ไม่ได้กำหนดซึ่งใช้ได้กับบางกรณี แต่ยังสามารถโยนข้อผิดพลาดได้
- สมมติว่าคุณกำลังพยายามเข้าถึงคุณสมบัติระดับบนสุดเท่านั้นซึ่งบางครั้งก็ใช้ได้สำหรับบางกรณี
- บังคับให้คุณใช้วิธีการที่เหมาะสมน้อยกว่าสัมพันธ์กับ PHP
isset()
เช่นisset(some, 'nested.deeper.value')
- ใช้
eval()
งานได้ แต่ฉันหลีกเลี่ยงเป็นการส่วนตัว
ฉันคิดว่าฉันครอบคลุมมาก มีบางประเด็นที่ฉันทำในคำตอบของฉันที่ฉันไม่ได้สัมผัสเพราะพวกเขา - แม้ว่าที่เกี่ยวข้อง - ไม่ใช่ส่วนหนึ่งของคำถาม แต่ถ้าจำเป็นฉันสามารถอัปเดตคำตอบของฉันพร้อมลิงก์ไปยังด้านเทคนิคเพิ่มเติมตามความต้องการ
ฉันใช้เวลากับ waaay มากเวลานี้หวังว่ามันจะช่วยให้ผู้คนออก
ขอบคุณสำหรับการอ่าน!