Day 12JSON, 에러 처리, 클래스

1. JSON.stringify / parse

const reading = { time: "11:00", tempC: 81.2, throttled: true };
const json = JSON.stringify(reading);          // '{"time":"11:00","tempC":81.2,"throttled":true}'
const back = JSON.parse(json);                    // 원래 객체로 (단, Date 등은 문자열로 남음)

JSON.stringify(reading, null, 2);                // 들여쓰기 2칸으로 예쁘게 출력할 때
JSON.parse는 형식이 안 맞으면 SyntaxError를 던진다. 외부에서 온 문자열(파일, API 응답, localStorage)을 파싱할 땐 항상 try/catch로 감싼다.

2. throw와 커스텀 에러

function parseReading(json) {
  try {
    const data = JSON.parse(json);
    if (typeof data.tempC !== "number") {
      throw new Error("tempC 필드가 없거나 숫자가 아님");
    }
    return data;
  } catch (err) {
    throw new Error(`센서 데이터 파싱 실패: ${err.message}`);
  }
}

3. class 문법

class SensorReading {
  #calibrationOffset = 0;          // # 붙이면 private 필드 — 클래스 밖에서 접근 불가

  constructor(time, tempC, throttled = false) {
    this.time = time;
    this.tempC = tempC;
    this.throttled = throttled;
  }

  isWarning() {                     // 인스턴스 메서드
    return this.tempC >= 65 && this.tempC < 80;
  }

  isDanger() {
    return this.tempC >= 80;
  }

  static fromJSON(json) {           // static — 인스턴스 없이 SensorReading.fromJSON(...)으로 호출
    const data = JSON.parse(json);
    return new SensorReading(data.time, data.tempC, data.throttled);
  }
}

const r = new SensorReading("11:00", 81.2, true);
r.isDanger()      // true
const r2 = SensorReading.fromJSON('{"time":"09:00","tempC":52.3}');
Rust의 impl 블록 = JS 클래스의 메서드들, Self::new(...) 같은 연관 함수 = static 메서드. 상속(extends)도 있지만 이 코스에선 다루지 않는다 — JS는 합성(composition)을 상속보다 선호하는 편이다.

🎯 실습 과제 — _submissions/day12.js

과제 1. SensorReading 클래스
위 예제와 같은 SensorReading 클래스를 직접 작성한다: constructor(time, tempC, throttled = false), isWarning(), isDanger() 메서드 포함.

과제 2. fromJSON 정적 메서드
SensorReading.fromJSON(json)을 구현하되, JSON 파싱에 실패하거나 tempC가 숫자가 아니면 "잘못된 센서 데이터: ..." 형식의 명확한 에러를 던진다 (try/catch로 감싸서 원인 메시지 포함).

// SensorReading.fromJSON('{"time":"11:00","tempC":81.2}') → SensorReading 인스턴스
// SensorReading.fromJSON('not json')                          → 에러 던짐

과제 3. 상태 라벨 메서드
label() 인스턴스 메서드를 추가한다: isDanger()"위험", isWarning()이면 "경고", 아니면 "정상"을 리턴.

과제 4 (도전). 배치 파싱
parseLog(jsonArrayString): JSON 배열 문자열을 파싱해서 각 항목을 SensorReading 인스턴스로 변환한 배열을 리턴한다. 배열 중 파싱 실패하는 개별 항목이 있어도 전체가 죽지 않고, 성공한 것만 모아서 리턴한다 (실패한 항목은 콘솔에 경고만 출력).

✅ 다 작성했으면:
cd ~/Documents/javascript-2주완성
bun _grade.ts day12