Skip to content

Latest commit

Β 

History

History

06-Type Coercion

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
Β 
Β 

νƒ€μž… λ³€ν™˜

λͺ…μ‹œμ  νƒ€μž…λ³€ν™˜(explict coercion) or νƒ€μž… μΊμŠ€νŒ…(type casting) 은 κ°œλ°œμžκ°€ μ˜λ„μ μœΌλ‘œ κ°’μ˜ νƒ€μž…μ„ λ³€ν™˜ν•˜λŠ” 것

암묡적 νƒ€μž…λ³€ν™˜(implicit coercion) or νƒ€μž… κ°•μ œ λ³€ν™˜(type coercion) 은 개발자의 μ˜λ„μ™€λŠ” 상관없이 ν‘œν˜„μ‹μ„ ν‰κ°€ν•˜λŠ” 도쀑에 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ μ•”λ¬΅μ μœΌλ‘œ νƒ€μž…μ΄ λ³€ν™˜λ˜λŠ” 것

  • λͺ…μ‹œμ  νƒ€μž…λ³€ν™˜μ΄λ‚˜ 암묡적 νƒ€μž…λ³€ν™˜μ΄ μ›μ‹œ κ°’(primitive value)을 직접 λ³€κ²½ν•˜λŠ” 것은 μ•„λ‹ˆλ‹€. β†’ λ³€κ²½ λΆˆκ°€λŠ₯ν•œ κ°’(immutable value)
  • 단지, κΈ°μ‘΄ μ›μ‹œ 값을 μ‚¬μš©ν•΄ λ‹€λ₯Έ νƒ€μž…μ˜ μƒˆλ‘œμš΄ μ›μ‹œ 값을 생성 ν•˜λŠ” 것


암묡적 νƒ€μž…λ³€ν™˜

μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진이 ν‘œν˜„μ‹μ„ 평가할 λ•Œ 개발자의 μ˜λ„μ™€λŠ” 상관없이 μ½”λ“œμ˜ λ¬Έλ§₯을 κ³ λ €ν•΄ μ•”λ¬΅μ μœΌλ‘œ 데이터 νƒ€μž…μ„ κ°•μ œ λ³€ν™˜(암묡적 νƒ€μž… λ³€ν™˜)ν•˜λŠ” 것

  • 암묡적 νƒ€μž… λ³€ν™˜μ΄ λ°œμƒν•˜λ©΄ β†’ λ¬Έμžμ—΄(string), 숫자(number), λΆˆλ¦¬μ–Έ(boolean) κ³Ό 같은 μ›μ‹œ νƒ€μž…(primitive type) 쀑 ν•˜λ‚˜λ‘œ νƒ€μž…μ„ μžλ™ λ³€ν™˜

λ¬Έμžμ—΄ νƒ€μž…μœΌλ‘œ λ³€ν™˜

// 🎯 μ£Όμ˜ν•  것 쀑심

// 숫자 νƒ€μž…
NaN + '';             // "NaN"
Infinity + ''         // "Infinity"

// null νƒ€μž…
null + '';            // "null"

// undefined νƒ€μž…
undefined + '';       // "undefined"

// μ‹¬λ²Œ νƒ€μž…
(Symbol()) + '';      // TypeError: Cannot convert a Symbol value to a string

// 객체 νƒ€μž…
({}) + '';            // "[object Object]"
Math + '';            // "[object Math]"
[] + '';              // ""
[10, 20] + '';        // "10,20"
(function(){}_ + '';  // "function(){}"
Array + '';           // "function Array() { [native code] }"

숫자 νƒ€μž…μœΌλ‘œ λ³€ν™˜

// λ¬Έμžμ—΄ νƒ€μž…
+""; // 0
+"0"; // 0
+"1"; // 1
+"string" + // NaN
  // λΆˆλ¦¬μ–Έ νƒ€μž…
  true; // 1
+false; // 0

// null νƒ€μž…
+null; // 0

// undefined νƒ€μž…
+undefined; // NaN

// μ‹¬λ²Œ νƒ€μž…
+Symbol(); // TypeError: Cannot convert a Symbol value to a number

// 객체 νƒ€μž…
+{}; // NaN
+[]; // 0
+[10, 20]; // NaN
+function () {}; // NaN
  • 빈 λ¬Έμžμ—΄(''), 빈 λ°°μ—΄([]), null, false β†’ 0
  • true β†’ 1
  • 객체, 빈 배열이 μ•„λ‹Œ λ°°μ—΄(= 값이 μžˆλŠ” λ°°μ—΄), undefined β†’ NaN ( 주의 ! )

λΆˆλ¦¬μ–Έ νƒ€μž…μœΌλ‘œ λ³€ν™˜

μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 λΆˆλ¦¬μ–Έ νƒ€μž…μ΄ μ•„λ‹Œ 값을 Truthy κ°’(참으둜 ν‰κ°€λ˜λŠ” κ°’) or Falsy κ°’(κ±°μ§“μœΌλ‘œ ν‰κ°€λ˜λŠ” κ°’) 으둜 κ΅¬λΆ„ν•œλ‹€.

// πŸ’‘ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진이 Falsy κ°’μœΌλ‘œ νŒλ‹¨ν•˜λŠ” κ°’

+ false
+ undefined
+ null
+ 0, -0
+ NaN
+ ''(빈 λ¬Έμžμ—΄)
  • Falsy κ°’ 을 μ œμ™Έν•œ λͺ¨λ“  값은 Truthy κ°’


λͺ…μ‹œμ  νƒ€μž… λ³€ν™˜

개발자의 μ˜λ„μ— 따라 λͺ…μ‹œμ μœΌλ‘œ νƒ€μž…μ„ λ³€κ²½ν•˜λŠ” λ°©λ²•μ—λŠ” λŒ€ν‘œμ μœΌλ‘œ λ‹€μŒκ³Ό κ°™λ‹€.

  • ν‘œμ€€ 빌트인(built-in) μƒμ„±μž ν•¨μˆ˜ β†’ String(), Number(), Boolean() 을 new ν‚€μ›Œλ“œ 없이 ν˜ΈμΆœν•˜λŠ” 방법
  • 빌트인(built-in) λ©”μ„œλ“œ μ‚¬μš©ν•˜λŠ” 방법
  • 암묡적 νƒ€μž…λ³€ν™˜

λ¬Έμžμ—΄ νƒ€μž…μœΌλ‘œ λ³€ν™˜

  1. String μƒμ„±μž ν•¨μˆ˜λ₯Ό new ν‚€μ›Œλ“œ 없이 ν˜ΈμΆœν•˜λŠ” 방법
  2. Object.prototype.toString λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 방법
  3. λ¬Έμžμ—΄ μ—°κ²° μ—°μ‚°μžλ₯Ό μ΄μš©ν•˜λŠ” 방법
// 1. String μƒμ„±μž ν•¨μˆ˜λ₯Ό  new ν‚€μ›Œλ“œ 없이 ν˜ΈμΆœν•˜λŠ” 방법
String(1);              // "1"
String(NaN);            // "NaN"
String(Infinity);       // "Infinity"

String(true);           // "true"
String(false);          // "false"

// 2. Object.prototype.toString λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 방법
(1).toString();         // "1"
(NaN).toString();       // "NaN";
(Infinity).toString();  // "Infinity"

(true).toString();      // "true"
(false).toString();     // "false"

// 3. λ¬Έμžμ—΄ μ—°κ²° μ—°μ‚°μžλ₯Ό μ΄μš©ν•˜λŠ” 방법
1 + '';                 // "1"
...

숫자 νƒ€μž…μœΌλ‘œ λ³€ν™˜

  1. Number μƒμ„±μž ν•¨μˆ˜λ₯Ό new ν‚€μ›Œλ“œ 없이 ν˜ΈμΆœν•˜λŠ” 방법
  2. parseInt, parseFloat ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 방법(λ¬Έμžμ—΄λ§Œ 숫자 νƒ€μž…μœΌλ‘œ λ³€ν™˜ κ°€λŠ₯)
  3. μ‚°μˆ  μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜λŠ” 방법
// 1. Number μƒμ„±μž ν•¨μˆ˜λ₯Ό new ν‚€μ›Œλ“œ 없이 ν˜ΈμΆœν•˜λŠ” 방법
Number("0"); // 0
Number("-1"); // -1
Number("10.53"); // 10.53

Number(true); // 1
Number(false); // 0

// 2. parseInt, parseFloat ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 방법(λ¬Έμžμ—΄λ§Œ 숫자 νƒ€μž…μœΌλ‘œ λ³€ν™˜ κ°€λŠ₯)
parseInt("0"); // 0
parseInt("-1"); // -1
parseInt("10.53"); // 10
parseFloat("10.53"); // 10.53

// μ‚°μˆ  μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜λŠ” 방법
+"0"; // 0

λΆˆλ¦¬μ–Έ νƒ€μž…μœΌλ‘œ λ³€ν™˜

  1. Boolean μƒμ„±μž ν•¨μˆ˜λ₯Ό new ν‚€μ›Œλ“œ 없이 ν˜ΈμΆœν•˜λŠ” 방법
  2. !(λΆ€μ • 논리 μ—°μ‚°μžλ₯Ό 두 번 μ‚¬μš©ν•˜λŠ” 방법
// 1. Boolean μƒμ„±μž ν•¨μˆ˜λ₯Ό new ν‚€μ›Œλ“œ 없이 ν˜ΈμΆœν•˜λŠ” 방법
Boolean('x');       // true
Boolean('');        // false
Boolean('false');   // true

Boolean(0);         // false
Boolean(1);         // true
Boolean(NaN);       // false
Boolean(Infinity);  // true

Boolean(null);      // false

Boolean(undefined); // false

Boolean({});        // true
Boolean([]);        // true

// 2. !(λΆ€μ • 논리 μ—°μ‚°μžλ₯Ό 두 번 μ‚¬μš©ν•˜λŠ” 방법
!!'x';  // true ( !(!'x') === !(false) -> true )
...


단좕 평가 πŸ”Ž

단좕 평가(short-circuit evaluation) : 논리 μ—°μ‚°μ˜ κ²°κ³Όλ₯Ό κ²°μ •ν•˜λŠ” ν”Όμ—°μ‚°μžλ₯Ό νƒ€μž… λ³€ν™˜ν•˜μ§€ μ•Šκ³  κ·ΈλŒ€λ‘œ λ°˜ν™˜

  • 단좕 ν‰κ°€λŠ” ν‘œν˜„μ‹μ„ ν‰κ°€ν•˜λŠ” 도쀑에 평가결과가 ν™•μ •λˆ 경우 β†’ λ‚˜λ¨Έμ§€ 평가 과정을 μƒλž΅ν•œλ‹€.
단좕 평가 ν‘œν˜„μ‹ 평가 κ²°κ³Ό
true ll anything true
false ll anything anything
true && anything anything
false && anything false

논리 μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•œ 단좕 평가

논리곱(&&) = 논리 μ—°μ‚°μ˜ κ²°κ³Όλ₯Ό κ²°μ •ν•˜λŠ” 것은 두 번째 ν”Όμ—°μ‚°μž

"Apple" && "Banana"; // Banana
  • 논리곱(&&) μ—°μ‚°μž λŠ” 두 개의 ν”Όμ—°μ‚°μžκ°€ λͺ¨λ‘ true둜 평가될 λ•Œ β†’ trueλ₯Ό λ°˜ν™˜
  • μ’Œν•­ -> μš°ν•­μœΌλ‘œ 평가가 진행

논리합(||) = 논리 μ—°μ‚°μ˜ κ²°κ³Όλ₯Ό κ²°μ •ν•˜λŠ” 것은 첫 번째 ν”Όμ—°μ‚°μž

"Apple" && "Banana"; // Apple
  • 논리합(||) μ—°μ‚°μž λŠ” λ‘κ°œμ˜ ν”Όμ—°μ‚°μž 쀑 ν•˜λ‚˜λ§Œ true둜 ν‰κ°€λ˜μ–΄λ„ β†’ trueλ₯Ό λ°˜ν™˜
  • μ’Œν•­ -> μš°ν•­μœΌλ‘œ 평가가 진행
// πŸ’‘ 논리 μ—°μ‚°μž 단좕 평가 - κΈ°λ³Έ

// 논리합(||) μ—°μ‚°
"Cat" || "Dog"; // "Cat"
false || "Dog"; // "Dog"
"Cat" || false; // "Cat"

// 논리곱(&&) μ—°μ‚°
"Cat" && "Dog"; // "Dog"
false && "Dog"; // "false"
"Cat" && false; // "false"
// πŸ’‘ 논리 μ—°μ‚°μž 단좕 평가 - ifλ¬Έ λŒ€μ²΄ -> κ°’ ν• λ‹Ή μ‹œ 깔끔함

var done = true;
var message = "";

// πŸ’© 쑰건문으둜 κ°’ ν• λ‹Ή
if (done) message = "κ°’";

// πŸ‘ 논리 μ—°μ‚°μž(논리곱)으둜 κ°’ ν• λ‹Ή
meessage = done && "κ°’";
// πŸ’‘ "객체"λ₯Ό 가리킀기λ₯Ό κΈ°λŒ€ν•˜λŠ” λ³€μˆ˜κ°€ null λ˜λŠ” undefined κ°€ μ•„λ‹Œμ§€ ν™•μΈν•˜κ³  ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•  λ•Œ
// κ°μ²΄λŠ” { ν‚€ : κ°’ } 으둜 κ΅¬μ„±λœ ν”„λ‘œνΌν‹°(property)의 집합
// 객체λ₯Ό 가리킀기λ₯Ό κΈ°λŒ€ν•˜λŠ” λ³€μˆ˜μ˜ 값이 객체가 μ•„λ‹Œ null μ΄λ‚˜ undefined 인 경우, 객체 μ°Έμ‘°μ‹œ TypeErrorκ°€ λ°œμƒ -> ν”„λ‘œκ·Έλž¨ κ°•μ œ μ’…λ£Œ

// πŸ’©
var elem = null;
var value = elem.value; // TypeError: Cannot read property 'value' of null

// πŸ‘
// elem이 null λ˜λŠ” undefined 같은 "Falsy κ°’"이면 elem κ°’μœΌλ‘œ 평가
// elem이 "Truthy κ°’"이면 elem.value 둜 평가
var elem = null;
var elem = elem && elem.value; // null
// πŸ’‘ ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜μ— 기본값을 μ„€μ •ν•  λ•Œ
// ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ 인수λ₯Ό μ „λ‹¬ν•˜μ§€ μ•ŠμœΌλ©΄ λ§€κ°œλ³€μˆ˜μ—λŠ” undefined κ°€ ν• λ‹Ή

// πŸ’© 인수λ₯Ό μ „λ‹¬ν•˜μ§€ μ•Šμ„ 경우
function getStringLength(str) {
  return str.length;
}
getStringLength(); // TypeError: Cannot read property 'length' of undefined

// πŸ‘ 단좕 평가λ₯Ό μ‚¬μš©ν•œ λ§€κ°œλ³€μˆ˜μ˜ κΈ°λ³Έκ°’ μ„€μ •
function getStringLength(str) {
  str = str || "";
  return str.length;
}
getStringLength(); // 0

// πŸ‘ Es6의 λ§€κ°œλ³€μˆ˜ default parameter μ„€μ •
function getStringLength(str = "") {
  return str.length;
}
getStringLength(); // 0

μ˜΅μ…”λ„ 체이닝 μ—°μ‚°μž

?. = μ˜΅μ…”λ„ 체이닝(optional chaining) μ—°μ‚°μž

  • μ’Œν•­μ˜ ν”Όμ—°μ‚°μžκ°€ null λ˜λŠ” undefined β†’ undefined λ°˜ν™˜
  • 그렇지 μ•Šμ€ 경우 β†’ μš°ν•­μ˜ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°
var elem = null;
var value = elem?.value; // undefined
  • 객체λ₯Ό 가리킀기λ₯Ό κΈ°λŒ€ν•˜λŠ” λ³€μˆ˜κ°€ null λ˜λŠ” undefinedκ°€ μ•„λ‹Œμ§€ ν™•μΈν•˜κ³  ν”„λ‘œνΌν‹°λ₯Ό μ•ˆμ „ν•˜κ²Œ μ°Έμ‘°ν•  λ•Œ 유용
  • μ˜΅μ…”λ„ 체이닝 λ„μž… μ΄μ „μ—λŠ”
    • 논리곱(&&)을 μ‚¬μš©ν•œ 단좕 평가λ₯Ό 톡해 β†’ λ³€μˆ˜κ°€ null λ˜λŠ” undefined 인지 ν™•μΈν–ˆμŒ
var elem = null;
var value = elem && elem.value; // null (elem의 null)
// πŸ’‘ 논리곱(&&) μ—°μ‚°μž vs μ˜΅μ…”λ„ 체이닝 μ—°μ‚°μž

// πŸ’© 논리곱(&&) μ—°μ‚°μž = μ’Œν•­ ν”Όμ—°μ‚°μžκ°€ Falsy값이면, μ’Œν•­ ν”Όμ—°μ‚°μžλ₯Ό κ·ΈλŒ€λ‘œ λ°˜ν™˜ν•œλ‹€. (단, 0 λ˜λŠ” ''은 객체둜 평가될 λ•Œλ„ μžˆλ‹€.)
var str = ""; //
var length = str && str.length; // ''

// πŸ‘ μ˜΅μ…”λ„ 체이닝 = μ’Œν•­ ν”Όμ—°μ‚°μžκ°€ Falsy값이라도 null λ˜λŠ” undefined 만 μ•„λ‹ˆλ©΄, μš°ν•­μ˜ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°ν•œλ‹€.
var str = "";
var length = str?.length; // 0

null 병합 μ—°μ‚°μž

?? = 병합 μ—°μ‚°μž(nullish coalescing) μ—°μ‚°μž

  • μ’Œν•­μ˜ ν”Όμ—°μ‚°μžκ°€ null λ˜λŠ” undefined β†’ μš°ν•­μ˜ ν”Όμ—°μ‚°μžλ₯Ό λ°˜ν™˜
  • 그렇지 μ•Šμ€ 경우 β†’ μ’Œν•­μ˜ ν”„λ‘œνΌν‹°λ₯Ό μ°Έμ‘°
var foo = null ?? "default string"; // "default string"
  • λ³€μˆ˜μ— 기본값을 μ„€μ •ν•  λ•Œ 유용 !
  • null 병합 μ—°μ‚°μž λ„μž… μ΄μ „μ—λŠ”
    • 논리합(||)을 μ‚¬μš©ν•œ 단좕 평가 λ₯Ό 톡해 β†’ λ³€μˆ˜μ— 기본값을 μ„€μ •ν–ˆμŒ
// πŸ’‘ 논리합(||) μ—°μ‚°μž vs null 병합 μ—°μ‚°μž

// πŸ’© 논리합(||) μ—°μ‚°μž = μ’Œν•­μ˜ ν”Όμ—°μ‚°μžκ°€ Falsy값이면, μš°ν•­μ˜ ν”Όμ—°μ‚°μžλ₯Ό λ°˜ν™˜ (단, 0 μ΄λ‚˜ ''은 κΈ°λ³Έκ°’μœΌλ‘œμ„œ μœ ν˜Έν•˜λ‹€λ©΄ 예기치 μ•Šμ€ λ™μž‘μ΄ λ°œμƒ !)
var foo = "" || "default string"; // "default string"

// πŸ‘ null 병합 μ—°μ‚°μž = μ’Œν•­μ˜ ν”Όμ—°μ‚°μžκ°€ Falsy값이라도 null λ˜λŠ” undefined κ°€ μ•„λ‹ˆλ©΄, μ’Œν•­μ˜ ν”Όμ—°μ‚°μžλ₯Ό κ·ΈλŒ€λ‘œ λ°˜ν™˜ν•œλ‹€.
var foo = "" ?? "default string"; // ''