👩🏻💼 "자바 스크립트는 동적 언어니까 타입 개념이 없을 거야"
👼🏻 "자바스크립트에도.. 타입이 있어요"
타입
: 자바 스크립트 엔진, 개발자 모두에게 특정 값들을 구별할 수 있게 해주는 고유한 집합내장 타입
null, undefined, boolean, number, string, object, symbol
typeof 연산자로 타입을 알 수 있음
null
null은 falsy한 유일한 원시값이지만, 타입은 object로 나옴 (황당)
typeof null === "object"
타입으로 null인지 알기 위해선 조건이 하나 더 필요함
var a = null;
(!a && typeof a === "object"); //true
변수와 값
변수엔 따로 타입이 없음
typeof (변수) = "이 변수에 들어있는 값의 타입이 뭐니?"
즉, 변수는 타입이 없지만 값은 타입이 있고
타입은 값의 내재된 특성을 정의함
undefined
값이 없는 변수의 값은 undefined
이때 undefined는 값이 없는 것이지 선언은 되어있는 상태를 의미함
typeof undefined = "undefined"
🔥 안전 가드
JS는 선언되지 않은 변수의 타입도 undefined로 반환함
👩🏻💼 "머야 헷갈리고 완전 구린 거 아니에요?"
👼🏻 "오히려 좋아"
선언되지 않은 변수를 체크하는 데에 사용할 수 있음!
if (선언되지 않은 변수) {
console.log("변수가 없어서 에러 발생");
}
if (typeof 변수 !== "undefined") {
console.log("안전하게 존재 여부 확인 가능")
}
의존성 주입 설계 패턴
특정 변수가 있는지 확인한 후 함수를 구현해야 할 때
function somethingCool(특정 변수) {
var helper = 특정 변수 ||
function() {
// somethingCool에서 제공하는 기본 기능
};
var val = helper();
// ...
}
특정 변수가 있으면 그대로 사용하고, 없으면 함수 바디를 정의함
👍🏻 다른 사람이 복붙을 해도 안전하게 특정 변수가 존재하는지 체크 가능함
배열
var a = [];
a.length; // 0
a[0] = 1;
a[1] = "2";
a[2] = [3];
a.length; // 3
key-value : 경악
var a = [];
a[0] = 1;
a["key"] = 2;
a.length; // 1
a["key"]; // 2
a.key; // 2
var a = [];
a["13"] = 42;
a.length; // 14
// 순식간에 0번 ~ 13번 인덱스가 생김
👉🏻 배열에 문자열 타입의 key를 두지말자.
만약 써야한다면 객체를 대응하고, 배열 원소의 인덱스는 반드시 숫자로 쓰기~
유사 배열
// arguments 객체
function foo() {
var arr = Array.prototype.slice.call(arguments);
arr.push("안녕하세요");
console.log(arr);
// ["변수1", "변수2", "안녕하세요"]
}
foo("변수1", "변수2");
// ES6 부터 기본 내장 함수 Array.from이 권장됨
var arr = Array.from(arguments);
// 함수의 인자를 리스트로 반환
문자열
js의 문자열은 문자 배열과 같지 않음
⭕ 공통점 : length, indexOf (ES5) , concat 사용 가능
❌ 차이점 : 문자열은 불변값이지만, 배열은 가변값임
Array.prototype.join.call
var a = "어쩔티비"
var b = Array.prototype.join.call(a, "-");
// Array 프로토타입 이용해서 배열 메소드 빌려쓰기
b;
// 어-쩔-티-비
문자열 -> 배열 -> 문자열
: 꼼수를 쓰자var a = "안되나요?"
a.reverse; // undefined
Array.prototype.reverse.call(a);
// "안되나요?"
var c = a.split("").reverse().join("");
// split : a를 문자의 배열로 분할함
// reverse : 문자 배열의 순서를 거꾸로 뒤집음
// join : 문자 배열을 합쳐 다시 문자열로 되돌림
c;
// ?요나되안
join("")
숫자
.toFixed(자릿수)
: 다음 자릿수에서 해당 자릿수로 반올림var num = 42.59;
a.toFixed(0); // 1 -> 0 : "43"
a.toFixed(1); // 2 -> 1 : "42.6"
a.toFixed(2); // 3 -> 2 : "42.59" ...
42.toFixed(3);
// error : 42인지 42.인지 알 수 없음
(42).toFixed(3);
0.42.toFixed(3);
42..toFixed(3);
부동 소수점
0.1 + 0.2 === 0.3;
// false
function isequal(n1, n2) {
return Math.abs(n1 - n2) < Number.EPSILON;
}
var a = 0.1 + 0.2;
var b = 0.3;
isequal(a, b); // true
특수 값
null
: 예전엔 값이 있었지만, 지금은 없는 상태undefined
: 값을 아직 가지지 못한 상태void 연산자
undefined는 void 연산자로도 얻을 수 있음
void ____ 는 어떤 값이든 무효로 만들어, 항상 결괏값을 undefined로 만듦
void 0
== void 1
== undefined
값이 존재해야 하는 곳에서 그 값이 undefined가 되어야 좋을 경우에만 사용하자!
특수문자
유효하지 않은 숫자
라고 보는 것이 좋다.var a = 2 / "메롱"; // NaN
typeof a === "number"; // true
난리났다 난리났어..
어쨌든 (NaN) 의 type은 "number"다.
게다가 NaN은 다른 어떤 NaN과도 동등하지 않음
NaN !== NaN
🤡 "isNaN을 사용하렴.. "
isNaN(a); // false
👼🏻 "Number.isNaN() 를 사용하면 됨"
ES6부터 등장한 요 폴리필을 쓰면 안전하게 체크 가능
NaN은 세상 모든 언어를 통틀어 "자기 자신과도 동등하지 않은
" 유일한 값임!
0
JS엔 +0, -0이 존재함
-0
----(문자열화) ----> "0"
"-0"
----(숫자화) ----> -0
-0을 문자열화 하면 항상 "0"이 나옴
(경악 1) 근데 반대로 문자열("-0")에서 숫자로 바꾸면 있는 그대로 보여줌
(경악 2) 비교를 할 때도 이와 비슷한 상황이 벌어짐
var a = 0;
var b = 0 / -3; // -0
a == b; // true
-0 == 0; // true
a === b; // true
-0 === 0; // true
Object.is
특이한 값을 비교할 땐 Object.is
를 사용하면 좋음
ex) NaN, -0, 0 등
특이한 값이 아니라면 그냥 ==, ===를 사용하자
값 VS 레퍼런스
js에서는 어떤 변수가 다른 변수를 참조할 수 없음
값의 타입
만으로 value-copy(값 복사) 인지, reference-copy(레퍼런스 복사) 인지 결정됨
var a = 2;
var b = a; // 'b'는 'a'에서 값을 복사함
b++;
a; // 2
b; // 3
var c = [1, 2, 3];
var d = c; // 'd'는 공유된 '[1, 2, 3]' 값의 레퍼런스
d.push(4);
c; // [1, 2, 3, 4]
d; // [1, 2, 3, 4]
var d = c.slice();