자바스크립트에서 선택적(null-safe)
15040 단어 webdevoptionaljavascriptnode
null
/undefined
처리에 대해 생각하게 되었습니다.짧은 배경
undefined
는 무엇입니까? undefined
는 선언된 변수, 존재하지 않는 속성 또는 함수 인수에만 제공되는 기본 값입니다.null
는 무엇입니까? null
는 값의 부재를 나타내는 또 다른 원시 값입니다.따라서 다음을 수행하면 어떻게됩니까?
let obj;
console.log(obj.someProp);
다음 오류가 발생합니다.
TypeError: Cannot read property 'someProp' of undefined
null
에서도 마찬가지입니다.널 검사
그렇다면 어떻게 피할 수 있습니까? 글쎄요, 우리는 자바스크립트에서
short-circuit
평가를 가지고 있어서 운이 좋았습니다. 즉, 이전 TypeError
을 피하기 위해 다음을 작성할 수 있습니다.
let obj;
console.log(obj && obj.someProp); // Prints undefined
그러나
obj.prop1.prop2.prop3
와 같이 더 깊이 들어가려면 어떻게 해야 합니까? 우리는 다음과 같은 많은 검사를 끝낼 것입니다:
console.log( obj && obj.prop1 && obj.prop1.prop2 && obj.prop1.prop2.prop3 );
역겹지 않나요?
그리고 해당 체인에
undefined
또는 null
가 있는 경우 기본값을 인쇄하려면 어떻게 해야 할까요? 그러면 더 큰 표현이 됩니다.
const evaluation = obj && obj.prop1 && obj.prop1.prop2 && obj.prop1.prop2.prop3;
console.log( evaluation != null ? evaluation : "SomeDefaultValue" );
다른 언어는 어떻게 하나요?
이 문제는 자바스크립트에만 있는 것이 아니라 대부분의 프로그래밍 언어에 존재하므로 일부 언어에서 null 검사를 수행하는 방법을 살펴보겠습니다.
자바
자바에는
Optional
API가 있습니다.
SomeClass object;
Optional.ofNullable(object)
.map(obj -> obj.prop1)
.map(obj -> obj.prop2)
.map(obj -> obj.prop3)
.orElse("SomeDefaultValue");
코틀린
kotlin(또 다른 JVM 언어)에는 elvis(
?:
) 및 safe-call( ?.
) 연산자가 있습니다.
val object: SomeClass?
object?.prop1?.prop2?.prop3 ?: "SomeDefaultValue";
씨#
마지막으로 C#에는 null 조건(
?.
) 및 null 병합( ??
) 연산자도 있습니다.
SomeClass object;
object?.prop1?.prop2?.prop3 ?? "SomeDefaultValue";
JS 옵션
그래서 이걸 다 보고 나서 자바스크립트로 그렇게 많이 쓰지 않을 수 있는 방법이 없을까 하는 생각이 들어서 regex로 실험을 시작하여 객체 속성에 안전하게 액세스할 수 있는 함수를 작성하기 시작했습니다.
function optionalAccess(obj, path, def) {
const propNames = path.replace(/\]|\)/, "").split(/\.|\[|\(/);
return propNames.reduce((acc, prop) => acc[prop] || def, obj);
}
const obj = {
items: [{ hello: "Hello" }]
};
console.log(optionalAccess(obj, "items[0].hello", "def")); // Prints Hello
console.log(optionalAccess(obj, "items[0].he", "def")); // Prints def
그 후 동일한 서명을 가진
lodash._get
에 대해 찾았습니다._.get(object, path, [defaultValue])
하지만 솔직히 말해서 저는 문자열 경로를 그다지 좋아하지 않기 때문에 문자열 경로를 피할 수 있는 방법을 찾기 시작한 다음 프록시를 사용하는 솔루션을 찾았습니다.
// Here is where the magic happens
function optional(obj, evalFunc, def) {
// Our proxy handler
const handler = {
// Intercept all property access
get: function(target, prop, receiver) {
const res = Reflect.get(...arguments);
// If our response is an object then wrap it in a proxy else just return
return typeof res === "object" ? proxify(res) : res != null ? res : def;
}
};
const proxify = target => {
return new Proxy(target, handler);
};
// Call function with our proxified object
return evalFunc(proxify(obj, handler));
}
const obj = {
items: [{ hello: "Hello" }]
};
console.log(optional(obj, target => target.items[0].hello, "def")); // => Hello
console.log(optional(obj, target => target.items[0].hell, { a: 1 })); // => { a: 1 }
미래
현재 다음을 수행할 수 있는 TC39 proposal이 있습니다.
obj?.arrayProp?[0]?.someProp?.someFunc?.();
꽤 깔끔해 보이죠? 그러나 이 제안은 아직 1단계이므로 이것이 js라는 것을 확인하려면 시간이 걸릴 것입니다. 그럼에도 불구하고 해당 구문을 사용할 수 있는 babelplugin이 있습니다.
종악장
null
는 한동안 존재했고 앞으로도 있을 것이며 프로그래밍에서 가장 싫어하는 개념 중 하나라고 확신합니다. 그러나 null-safety를 확보하는 방법이 있습니다. 여기에 두 센트를 게시했습니다. 어떻게 생각하는지 또는 다른 대안이 있으면 알려주세요.p.s.: 여기 좀 예쁘다 gist
Reference
이 문제에 관하여(자바스크립트에서 선택적(null-safe)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/pichardoj/optional-null-safe-in-javascript-1b7k텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)