본문 바로가기

카테고리 없음

[ Javascript ] truthy와 falsy, null check, Java의 Serializable 인터페이스 맛보기

Truthy와 Falsy

 

자바스크립트에서 truthy value는 Boolean타입으로 이루어진 식?에서 true로 간주된 value다.

falsy로 정의된 것이 아니라면 모든 값은 truthy다 → falsy로 정의된: false, 0, -0, 0n, ""(빈문자열), null, undefined, NaN 등을 제외한 모든 값들은 truthy다. 자바스크립트는 boolean contexts에서(boolean타입이 반환되어야 하는? 타입 자동 변환?(타입을 강제로 바꾸는)을 사용한다.

 

자바스크립트에서 truthy value(boolean contexts에서 true로 평가되는, 그래서 if 블록문이 실행될 것이다)의 예시

***boolean contexts라는 것은 boolean 타입의 데이터를 전달받아야 하는 위치, boolean 타입을 반환해야하는 장소를 의미하는 것 같다. 예를 들면 if()문의 조건식은 boolean 타입을 반환해야 하기 때문에 이런 장소? 위치를 boolean contexts라고 할 수 있을 것 같다. 

 

if(true) { console.log("true");}--> 조건식이 true이므로 {}블록문 실행
// if({}), if([]) --> 빈 객체, 빈 배열을 boolean 타입으로 변환했을 때 true를 반환하기 때문에
// 블록문이 실행된다. boolean 타입으로 반환하는 방법 ---> a = Boolean({}); console.log(a); // true출력

if({})
if([])
if( /* 0과 -0, 0n을 제외한 어떠한 숫자가 오더라도 true를 반환한다. */ 1)

// ""빈 문자열을 제외하고(문자열의 길이가 0이 아니라면) 값이 있는 문자열은 true를 반환한다.
// ""문자열 형식에 공백문자 또한 문자열의 길이로 카운트 되기 때문에
// 공백있는 문자열 " "또한 true를 반환한다.
if("0" /* 숫자 0이 아니다, 문자열 0이다. 그렇기 때문에 true를 반환함*/)

if(new Date()) // 객체가 null이 아니라면 모든 객체는 true를 반환한다.

 

 

***자바스크립트에는 '값이 없음'을 나타내는 값이 두 개 있는데, null과 undefined다.

사용하는 목적과 위치가 다르다.  undefined는 정의되지 않은 이라는 의미로, 값이 대입되지 않은 변수(선언만한 변수) 그리고 객체에 선언하지 않은 속성을 사용하려고 하면 undefined의 결과를 반환한다. null은 '객체가 없음'을 의미한다. null의 타입은 객체로 ( 콘솔창에 console.log(typeof null); 을 작성하면 null의 타입이 object라는 것을 확인할 수 있음), 프로그래머 입장에서 명시적으로 값이 없다는 것을 명시하고 싶다면 null을 사용한다. 명시적으로 null을 사용함으로써 코드의 명확성이 분명해진다.

undefined는 개발자가 명시적으로 대입하는 것이 아닌 코드를 작성하다가 실행했을 때 어떤 변수에 값이 대입되어있지 않거나 어떤 객체에 선언되어 있지 않은 속성을 사용하려고 할 때 "사용하려는 그 변수에 대입되어 있는 값은 없다"는 것을 알려주는 용도?로 사용되어 개발자가 그것을 인지하고 코드를 수정하게 되는 결과에 이르는 것 같다.

 

***객체에 값이 없을 때(null), 변수에 값이 대입되어 있지 않거나 객체에 선언하지 않은 속성을 사용했을 때(undefined)

null과 undefined가 출력되는데, 이럴 경우를 대비해 문제 방지를 위해 null의 여부를 확인해주어야 한다.

 

***Null check

'객체가 없음'을 개발자가 명시적으로 나타내거나 혹은 반환되는 객체의 값이 null인경우,

변수를 선언만하고 값이 대입되지 않은 경우, 객체가 갖고 있지 않은 속성을 사용할 경우에 undefined 값을 반환하게 되는데

그런 경우를 고려해서 값의 유무를 확인해야 되고, 값이 없는지를 확인하기 위해서 null check를 해주어야 한다.

값이 있는 경우와 값이 없는 경우(null 또는 undefined)를 고려해서 코드를 작성해야 한다.

 

null check하는 방법: 등호 사용하기

값이 없음을 체크해서 값이 없을 경우 프로그램을 어떻게 반응?할 것인지를 고려해 코드를 작성해야 하기 때문에 null check는 중요한듯. 값이 있을 경우보다는 값이 없을 경우의 모든 수를 고려해서 작성하는 것이 중요할 듯 하다.

우선 null을 체크하는 함수를 정의할 것이니 함수명을 isEmpty로 하자

const isEmpty = function(value) {...};

 

1. 객체가 null일 경우

if(value == null) return true;

 

1) 객체는 생성됐지만 객체안에 속성이 없어서 빈 객체일 경우 {}

--> 여기서 배열이 들어올 수도 있다. 그래서 객체와 배열의 차이를 두기 위해 타입으로 비교하려고 했는데

자바스크립트에서는 배열과 객체의 타입이 object다. 그리고 객체의 경우 Object.keys(객체).length 했을 때,

객체가 갖고 있는 속성들의 길이를 구하니까 0이라면 빈 객체, 배열의 경우 Object.keys(배열).length 했을 때,

역시 배열이 갖고 있는 요소의 갯수가 들어오므로 0이라면 빈 배열일 것이다. 그래서 타입을 체크할 필요가 없다.

어쨌든 둘 다 이 조건식을 통과한다면 빈 객체, 빈 배열이라는 의미니까

if(value != null && Object.keys(value).length === 0) return true;

***빈 객체를 참조하는[가리키는] 참조변수를 if()문의 조건식에 사용했더니 undefined가 출력됨. 그런데 console.log()로 찍어보면 빈 객체가 출력됨. 빈 객체, 빈 배열을 참조하는 참조변수는 null은 아니나 해당 참조변수를 조건식 등에 사용한다면 undefined가 출력됨.

 

2. 변수를 선언했으나 값이 대입되지 않은 경우, 선언된 객체가 갖고 있지 않은 속성을 사용한 경우 defined 결과를 반환한다.

let a;

console.log(a); // undefined

변수 a의 타입은 undefined --> console.log(typeof a);

 

if(value == undefined) return true;

 

3.  사용자로부터 입력받은 값을 사용할 경우, 사용자가 아무것도 입력하지 않을 수 있으니

전달받은 인자가 빈 문자열인지를 체크할 것 value == "", 근데 공백도 체크해야 하니까 공백을 없애는 작업을 한 후에 빈 문자열인지를 체크하는 게 맞지 않나? 그래서 문자열이 빈 값인지(""빈문자열, "            "빈 공백) 두 가지 경우의 수를 고려해서

 

우선 전달받은 인자의 타입이 string인 경우, string의 길이(크기)비교해서 확인해보자

trim()을 한 이유는 공백으로만 이루어진 문자열일 수도 있기 때문에 공백으로만 이루어진 문자열인 경우

공백을 모두 제거하고, 길이를 비교한다. 공백을 모두 제거했을 때 0이라면 전달받은 인자는 데이터가 아무것도 없는 값인 경우다.

(""빈 문자열인 경우와 "                  "빈 공백이 하나 이상의 문자열인 경우)

if(typeof value === 'string' && value.trim().length === 0)

 

위 4개의 경우의 수를 함수의 블록내부에서 체크하도록 조합해서 작성하면

const isEmpty = function(value) {
	return (
     	// == 동등비교 연산자이므로 null과 undefined를 동일하게 여겨
        // null과 undefined인지를 모두 체크한다. 그래서 value == null 이거 하나만 작성해도 좋다.
    	value == null ||
        value == undefined ||
        
        (typeof value === 'string' && value.trim().length === 0) ||
        
        // 빈 배열 체크
        // 1. 우선 배열인지를 먼저 체크하고,
        // 2. 배열이라면 true를 반환하니까 우항의 피연산자를 평가한다.
        // 우항의 피연산자는 배열의 길이가 0인지를 확인하는 0이라면 요소가 없는 것으로
        // 결과적으로 빈 배열을 의미하면서 true를 반환한다.
        Array.isArray(value) && value.length === 0)

        (typeof value === 'object' && Object.keys(value).length === 0)

    );
}

 

 

---------------------------------------

 

value object라고도 불리는 transfer object는 데이터를 전송하기 위한 객체를 만들기 위한 클래스(설계도)?라고 생각해도 될 것 같음. 데이터를 전송하기 위한 객체를 만들려면 객체를 만들기 위한 설계도가 필요하고, 그 설계도는 클래스, transfer object는 데이터를 전송하기 위한 객체에 대한 패턴이 작성된 클래스다. 값을 전달하기 위한 패턴이 작성된 클래스를 통해 객체를 만들고, 그 객체를 통해 여러 종류의 데이터를 얻거나 설정할 수 있다. 패턴을 작성할 때 필드에 private 제한자를 붙이면 외부에서 값에 직접적으로 접근할 수 없기에 객체가 갖고 있는 값을 간접적으로 얻거나 설정할 수 있도록 getter(), setter() 메서드를 작성해주어야 한다.

 

클래스를 정의할 때 클래스의 멤버변수가 private접근제한자를 갖게 되면 외부에서 해당 클래스로부터 객체를 생성할 때 객체로 직접 접근하여 값을 얻거나 설정할 수 없다. 그래서 외부에서도 접근이 가능하도록 설계를 해야하는데 이 때 사용되는 메서드가 getter, setter 메서드다. getter, setter 메서드를 사용하면 외부에서 직접 값에 접근하지 못하기 때문에 데이터를 보호할 수 있다. 예를 들어 나이를 설정할 때 사람의 나이는 1부터 시작되므로 1미만의 값이 들어오면 "옳지 않은 값입니다."의 메시지를 사용자에게 보여주면서 올바른 값을 입력하도록 유도할 수 있고, 옳지 않은 값을 설정하지 않음으로써 프로그램 오류 방지를 향상시킬 수 있다. transfer object를 만들 수 있는 틀인 클래스를 잘 설계해 놓으면 나중에 null 체크를 일일이 해야하는 번거로움을 줄일 수 있다고 한다.

transfer object 패턴을 사용하는 이유는 하나의 객체에 결과값을 담아올 수 있어 두 번 세 번씩 요청하는 일이 발생하는 것을 줄여주기 때문이다.

 

java.io.Serializable

 

***serial: (텔레비전·라디오의) 연속극; (잡지의) 연재물;  순차적인; (같은 일을 여러 번) 계속하는, 상습적인[연쇄적인], 연속 방송되는, 연재되는; (데이터 전송이·연산이) 직렬의

 

직렬화가 가능한 → 직렬화가 무엇인가?

직렬화란 자바 내부에서 사용되는 객체 또는 데이터를 외부의 자바시스템에서도? (→ 자바 외부의 시스템에서도 이렇게 작성해야 되지 않나?) 사용할 수 있도록 바이트(byte) 형태로 데이터를 변환하는 메커니즘이다. 자바 객체를 네트워크를 통해 전송하거나 DB나 파일에 객체 내용을 그대로 저장할 때도 필요하다. SerialVersionUID?

 

Serializable 인터페이스를 보면

public interface Serializable { }

 

이 인터페이스를 구현한 객체는 구현해야할 메서드가 하나도 없다.

이 인터페이스를(java.io.Serializable) 클래스가 구현해야하는 경우는 뭐가 있을까? 

이 인터페이스가 (java.io.Serializable) 하는 일은 무엇일까?

 

Serializable 인터페이스를 구현하면 객체를 직렬화할 수 있다.

서버 사이의 데이터 전송이 가능해진다. 원격지 서버에 데이터를 전송하거나,

파일로 객체를 저장할 경우에는 Serializable 인터페이스를 구현해야 한다.

 

객체를 직렬화한다는 것, 아직 잘 이해가지 않는다. 우선 오늘까지 공부한 내용을 올리고,

Serializable 인터페이스는 추후에 다시 정리해서 올릴 예정이다.