Umur utas lama, tetapi ada cara baru untuk menjalankan yang setara isset()
.
ESNext (Tahap 4 Desember 2019)
Dua sintaks baru memungkinkan kami untuk sangat menyederhanakan penggunaan isset()
fungsi:
Harap baca dokumen dan perhatikan kompatibilitas browser.
Jawaban Sebelumnya
Lihat penjelasan di bawah ini. Catatan saya menggunakan sintaks StandardJS
Contoh Penggunaan
// 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
Fungsi Jawab
/**
* 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
}
}
Penjelasan
PHP
Perhatikan bahwa dalam PHP Anda dapat mereferensikan variabel apa pun pada kedalaman apa pun - bahkan mencoba mengakses non-array sebagai array akan mengembalikan yang sederhana true
atau 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
Dalam JavaScript, kami tidak memiliki kebebasan itu, kami akan selalu mendapatkan kesalahan jika kami melakukan hal yang sama karena JS segera berusaha mengakses nilai deeper
sebelum kami dapat membungkusnya dalam isset()
fungsi kami jadi ...
// 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
Alternatif yang lebih banyak gagal:
// 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
Dan beberapa alternatif kerja yang bisa menjadi redundan dengan cepat:
// 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
Kesimpulan
Semua jawaban lain - meskipun sebagian besar layak ...
- Asumsikan Anda hanya memeriksa untuk melihat apakah variabel tidak terdefinisi baik untuk beberapa kasus penggunaan tetapi masih bisa melempar Kesalahan
- Anggap Anda hanya mencoba mengakses properti tingkat atas, yang lagi baik untuk beberapa kasus penggunaan
- Memaksa Anda untuk menggunakan pendekatan yang kurang ideal dibandingkan dengan PHP
isset()
misalnyaisset(some, 'nested.deeper.value')
- Gunakan
eval()
yang berfungsi tetapi saya pribadi hindari
Saya pikir saya sudah membahas banyak hal. Ada beberapa poin yang saya buat dalam jawaban saya yang tidak saya sentuh karena mereka - meskipun relevan - bukan bagian dari pertanyaan. Namun, jika perlu, saya dapat memperbarui jawaban saya dengan tautan ke beberapa aspek yang lebih teknis berdasarkan permintaan.
Saya menghabiskan banyak waktu untuk hal ini sehingga mudah-mudahan ini membantu orang keluar.
Terima kasih telah membaca!