오래된 스레드이지만 이에 상응하는 새로운 방법이 있습니다. isset()
.
ESNext (2019 년 12 월 4 일)
두 가지 새로운 구문을 통해 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에서는 어떤 깊이에서든 변수를 참조 할 수 있습니다. 배열로 배열이 아닌 항목에 액세스하려고해도 단순 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
결론
다른 모든 답변-대부분 실행 가능하지만 ...
- 변수가 정의되지 않았는지 확인하고 일부 사용 사례에는 적합하지만 여전히 오류가 발생할 수 있다고 확인한다고 가정하십시오.
- 최상위 속성에만 액세스하려고한다고 가정 해 봅시다.
isset()
예를 들어 PHP에 비해 덜 이상적인 접근 방식을 사용하도록하십시오.isset(some, 'nested.deeper.value')
eval()
어떤 작품을 사용 하지만 개인적으로 피하십시오
나는 그것을 많이 덮었다 고 생각합니다. 내 대답에는 내가 관련이 있지만 질문의 일부가 아니기 때문에 다루지 않는 몇 가지 사항이 있습니다. 그러나 필요한 경우 수요에 따라보다 기술적 측면에 대한 링크로 답변을 업데이트 할 수 있습니다.
나는 이것에 많은 시간을 보냈으므로 사람들이 도움이되기를 바랍니다.
읽어 주셔서 감사합니다!