[TIL] Day15 #JS_Koans

tnqls1211vยท2022๋…„ 5์›” 16์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
15/120
post-thumbnail

[TIL] Day15
[SEB FE] Day15

๐Ÿซ  ๊ธˆ์š”์ผ 3์‹œ๊ฐ„์— ์ด์–ด ์˜ค๋Š˜ 5์‹œ๊ฐ„ ๊ฝ‰๊ฝ‰ ์ฑ„์›Œ์„œ ํŽ˜์–ด๋ถ„๊ณผ JS koans 50๋ฌธ์ œ ๋๊นŒ์ง€ ํ’€์—ˆ๋‹ค.

โ˜‘๏ธย JS Koans ๊ฐœ๋… ์ •๋ฆฌ

02. Types-part1.js

โœ‹ย ๋Š์Šจํ•œ ๋น„๊ต ์—ฐ์‚ฐ(==)์„ ์ง€์–‘ํ•˜๊ณ , ์—„๊ฒฉํ•œ ๋น„๊ต ์—ฐ์‚ฐ(===) ์‚ฌ์šฉํ•˜๊ธฐ

03. LetConst.js

โœ‹ย var, const, let ๋น„๊ต

  • var ํ‚ค์›Œ๋“œ๋Š” ์ง€์–‘!
  • const ํ‚ค์›Œ๋“œ๋Š” ์žฌํ• ๋‹น ๋ถˆ๊ฐ€๋Šฅ โŒ
  • let ํ‚ค์›Œ๋“œ๋Š” ์žฌํ• ๋‹น ๊ฐ€๋Šฅ โญ•๏ธ

04. Scope.js

  • Hoisting(ํ˜ธ์ด์ŠคํŒ…): function์ด๋‚˜ var ์„ ์–ธ๋ฌธ ๋“ฑ์„ ํ•ด๋‹น ์Šค์ฝ”ํ”„์˜ ์„ ๋‘๋กœ ์˜ฎ๊ธด ๊ฒƒ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋Š” ํŠน์„ฑ
    • ์šฐ๋ฆฌ๊ฐ€ ์˜ˆ์ƒํ•˜์ง€ ์•Š์€ ๊ฒฐ๊ณผ๋กœ์จ, ์ข‹์€ ํ˜„์ƒ์€ ์•„๋‹ˆ๋ฏ€๋กœ ์ง€์–‘.
  • TDZ(Temporal Dead Zone): ์Šค์ฝ”ํ”„์˜ ์‹œ์ž‘ ์ง€์ ๋ถ€ํ„ฐ ์ดˆ๊ธฐํ™” ์‹œ์ž‘ ์ง€์ ๊นŒ์ง€์˜ ๊ตฌ๊ฐ„
    • TDZ๋Š” ์„ ์–ธ ์ „์˜ ๋ณ€์ˆ˜ ์‚ฌ์šฉ์„ ํ—ˆ์šฉํ•˜์ง€ ์•Š์Œ
    • ๋ฐ˜๋Œ€๋กœ var ํ‚ค์›Œ๋“œ๋Š” ์„ ์–ธ ์ „์—๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ var ์‚ฌ์šฉ ์ง€์–‘

ย โœ‹ย ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ & ํ•จ์ˆ˜ ํ‘œํ˜„์‹ ์ฐจ์ด โ†’ ํ˜ธ์ด์ŠคํŒ…(hoisting)

  • ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ โ† ํ˜ธ์ด์ŠคํŒ… ๋ฐœ์ƒ โญ•๏ธ
  • ํ•จ์ˆ˜ ํ‘œํ˜„์‹ โ† ํ˜ธ์ด์ŠคํŒ… ๋ฐœ์ƒ โŒย (์ผ์–ด๋‚˜์ง€ ์•Š๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž„)
// ํ•จ์ˆ˜ ์„ ์–ธ๋ฌธ: function ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•จ์ˆ˜ ์„ ์–ธ
function add (x, y) {
	return x + y;
};

// ํ•จ์ˆ˜ ํ‘œํ˜„์‹: ํ•จ์ˆ˜๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•œ ํ˜•ํƒœ
const add = function (x, y) {
	return x + y;
};

โœ”๏ธย ํด๋กœ์ €(Closure)

  • ๋‚ด๋ถ€ ํ•จ์ˆ˜ โ†’ ์™ธ๋ถ€ ํ•จ์ˆ˜์˜ ์ „์—ญ ๋ณ€์ˆ˜์— ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ์™ธ๋ถ€ ํ•จ์ˆ˜ โ†’ ๋‚ด๋ถ€ ํ•จ์ˆ˜์˜ ์ง€์—ญ ๋ณ€์ˆ˜์— ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅ
function increaseBy(increaseByAmount) {
  return function (numberToIncrease) {
    return numberToIncrease + increaseByAmount;
  };
}

const increaseBy3 = increaseBy(3);
const increaseBy5 = increaseBy(5);

increaseBy3(10);  // 13
increaseBy5(10);  // 15
increaseBy(8)(6) + increaseBy(5)(9);  // 28
// ์ „์—ญ ๋ณ€์ˆ˜
let age = 27;
let name = "jin";
let height = 179;

function outerFn() {
	let age = 24;     // ์ง€์—ญ๋ณ€์ˆ˜
	name = "jimin";   // ์ „์—ญ๋ณ€์ˆ˜ name ๊ฐ’์ด 'jin' -> 'jimin'์œผ๋กœ ์žฌํ• ๋‹น
	let height = 178; // ์ง€์—ญ๋ณ€์ˆ˜

	function innerFn() {
		age = 26;           // ์ง€์—ญ๋ณ€์ˆ˜ age ๊ฐ’์ด 24 -> 26์œผ๋กœ ์žฌํ• ๋‹น
		let name = "suga";  // ์ง€์—ญ๋ณ€์ˆ˜
		return height;
	}

	innerFn();

	age;  // outFn ๋‚ด์˜ 26(์ง€์—ญ๋ณ€์ˆ˜)
	name; // outerFn ๋‚ด์˜ ์ „์—ญ๋ณ€์ˆ˜ 'jimin'
	// innerFn() ๋‚ด์— ์„ ์–ธ๋œ ์ง€์—ญ๋ณ€์ˆ˜๋ฅผ ํ•จ์ˆ˜ ๋ฐ–์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ
}

const innerFn = outerFn();

age;       // 27(์ „์—ญ๋ณ€์ˆ˜)
name;      // 'jimin'(์ „์—ญ๋ณ€์ˆ˜)
innerFn(); // 178(์ง€์—ญ๋ณ€์ˆ˜)

05. ArrowFunction.js (ํ™”์‚ดํ‘œ ํ•จ์ˆ˜)

const add = (x, y) => {
	return x + y;
};

add(10, 20);  // 30

----------

// return ์ƒ๋žต
const subtract = (x, y) => x - y;
subtract(10, 20);  // -10

----------

// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด์„œ ํด๋กœ์ € ํ‘œํ˜„
const adder = (x) => {
	return (y) => {
		return x + y;
	};
};

adder(50)(10);  // 60

----------

const subtractor = (x) => (y) => {
	return x - y;
};

subtractor(50)(10);  // 40

06. Types-part2.js (์›์‹œ&์ฐธ์กฐ ์ž๋ฃŒํ˜•)

โœ”๏ธย ์›์‹œ ์ž๋ฃŒํ˜•

  • ๊ฐ’ ์ž์ฒด์— ๋Œ€ํ•ด ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅ (์ƒˆ๋กœ์šด ๋ณ€์ˆ˜์— ์ƒˆ๋กœ์šด ๊ฐ’์œผ๋กœ ์žฌํ• ๋‹น์€ ๊ฐ€๋Šฅ) โ‡’ ์›์‹œ ์ž๋ฃŒํ˜•์„ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ๊ฒฝ์šฐ, ๊ฐ’ ์ž์ฒด์˜ ๋ณต์‚ฌ๊ฐ€ ์ผ์–ด๋‚จ (immutable)
let name = "carpediem";
name.toUpperCase();  // "CARPEDIEM"
name; // "carpediem"
name = name.toUpperCase();
name; // "CARPEDIEM"

----------

let word = true;
let copyWord = word;

word = false;
word;     // false;
copyWord; // true;

โœ”๏ธย ์ฐธ์กฐ ์ž๋ฃŒํ˜•

  • ์ฐธ์กฐํ˜•์€ ์ฃผ์†Œ๋ฅผ ํ• ๋‹น (mutable)
  • ์ฐธ์กฐ ์ž๋ฃŒํ˜•์˜ ๋ฐ์ดํ„ฐ๋Š” ๋™์ (dynamic)์œผ๋กœ ๋ณ€ํ•จ
  • ์ฐธ์กฐ ์ž๋ฃŒํ˜•์„ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ์˜ ์ฃผ์†Œ๊ฐ€ ์ €์žฅ
  • ๋ฐ์ดํ„ฐ๋Š” ์–ธ์ œ๋“  ๋Š˜์–ด๋‚˜๊ณ  ์ค„์–ด๋“ค ์ˆ˜ ์žˆ์Œ (๋™์ ์œผ๋กœ ๋ณ€ํ•จ) โ†’ ์ด๋ฅผ ๋” ์ž˜ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํŠน๋ณ„ํ•œ ์ €์žฅ๊ณต๊ฐ„(heap)์˜ ์ฃผ์†Œ๋ฅผ ๋ณ€์ˆ˜์— ํ• ๋‹น
const nums1 = [1, 2, 3];  // [1, 2, 3]์ด heap์— ์ €์žฅ, ์ด ์œ„์น˜์˜ ์ฃผ์†Œ๊ฐ€ ๋ณ€์ˆ˜ num1์— ์ €์žฅ
const nums2 = [1, 2, 3];  // [1, 2, 3]์ด heap์— ์ €์žฅ, ์ด ์œ„์น˜์˜ ์ฃผ์†Œ๊ฐ€ ๋ณ€์ˆ˜ num2์— ์ €์žฅ
nums1 === nums2;  // false
// ์ฐธ์กฐ ์ž๋ฃŒํ˜•(๋ฐฐ์—ด, ๊ฐ์ฒด)์˜ ๋น„๊ต๋Š” ์ฃผ์†Œ ๋น„๊ต

// heap์—๋Š” ๋‘ ๊ฐœ์˜ [1, 2, 3]์ด ์ €์žฅ๋˜์–ด ์žˆ์œผ๋ฉฐ,
// ๊ฐ๊ฐ์— ๋Œ€ํ•œ ์ฃผ์†Œ๊ฐ€ ๋ณ€์ˆ˜ num1, num2์— ์ €์žฅ

07. Array.js

const arr = ["peanut", "butter", "and", "jelly"];

// arr.slice๋Š” arr์˜ ๊ฐ’์„ ๋ณต์‚ฌํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋ฆฌํ„ด
arr.slice(1);    // ["butter", "and", "jelly"]
arr.slice(2, 2); // []
arr.slice(3, 0); // []
arr.slice(5, 1); // []
arr.slice(0);    // ["peanut", "butter", "and", "jelly"] <- arr ์ „์ฒด ๋ณต์‚ฌ

----------

const arr = ["zero", "one", "two", "three", "four", "five"];
const assignedArr = arr;
assignedArr[5] = "changed in assignedArr";
arr[5]; // "changed in assignedArr"

const copiedArr = arr.slice();  // ์›๋ณธ ๋ฐฐ์—ด ๋ณ€๊ฒฝ X
copiedArr[3] = "changed in copiedArr";
arr[3]; // "three"

โœ‹ย ๋ฐฐ์—ด๋„ ๊ฐ์ฒด (typeof โ†’ โ€˜objectโ€™)

  • ์–•์€ ๋ณต์‚ฌ: ์ฃผ์†Œ๋งŒ ๋ณต์‚ฌ (๋ณต์‚ฌ๋œ ๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด๋„ ์›๋ณธ ๊ฐ์ฒด๋Š” ๊ทธ๋Œ€๋กœ)
  • ๊นŠ์€ ๋ณต์‚ฌ: ์ฃผ์†Œ๊ฐ€ ๋‹ค๋ฆ„

08. Object.js

const emptyObj = {};
typeof emptyObj === 'object';  // true
emptyObj.length;  // undefined
// ๊ฐ์ฒด์˜ ๊ธธ์ด๋Š” ์—†์Œ. => undefined

----------

const obj = {
	mastermind: "Joker",
	henchwoman: "Adam West",
	relations: ["Anarky", "Duela Dent", "Lucy"],
	twins: {
    "Jared Leto": "Suicide Squad",
    "Joaquin Phoenix": "Joker",
    "Heath Ledger": "The Dark Knight",
    "Jack Nicholson": "Tim Burton Batman",
  }
};

const assignedObj = obj;
assignedObj["relations"] = [1, 2, 3];
obj["relations"];  // [1, 2, 3] (์›๋ณธ ๊ฐ์ฒด ๋ณ€๊ฒฝ)

const copiedObj = Object.assign({}, obj);  // Object.assgin() <- ์–•์€ ๋ณต์‚ฌ
copiedObj.mastermind = "James Wood";
obj.mastermind;  // "Joker"

obj.henchwoman = "Harley";
copiedObj.henchwoman = "Adam West"

delete obj.twin["Jared Leto"];
"Jared Leto" in copiedObj.twins;  // false (์›๋ณธ ๊ฐ์ฒด๊ฐ€ ์‚ญ์ œ๋˜๋ฉด ๋ณต์‚ฌ๋œ ๊ฐ์ฒด ๊ฐ’๋„ ์‚ญ์ œ)

โœ”๏ธย this

  • this๋Š” method๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์‹œ์ ์— ๊ฒฐ์ •๋จ
  • this๋Š” ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ์— ๋”ฐ๋ผ์„œ ๊ฐ’์ด ๋‹ฌ๋ผ์ง€๊ธฐ๋„ ํ•จ

ย โœ‹ย method๋Š” '์–ด๋–ค ๊ฐ์ฒด์˜ ์†์„ฑ์œผ๋กœ ์ •์˜๋œ ํ•จ์ˆ˜โ€™

โ‡’ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์€ ์–ด๋– ํ•œ ๊ฐ์ฒด์˜ method์ธ๋ฐ, ๊ทธ '์–ด๋– ํ•œ ๊ฐ์ฒด'๋ฅผ ๋ฌป๋Š” ๊ฒƒ์ด this

ย โœ‹ย ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ์ž์‹ ์˜ this๊ฐ€ ์—†์Œ

09. SpreadSyntax.js

const spread = [1, 2, 3];
const arr = [0, spread, 4];
arr;  // [0, [1, 2, 3], 4]

----------

const spread = [];
const arr = [0, spread, 1];
arr;  // [0, [], 1]

----------

// Rest
function returnSecondArg(firstArg, secondArg) {
  return secondArg;
};

returnSecondArg("only give first arg");  // undefined (secondArg์— ์ „๋‹ฌํ•ด์ฃผ๋Š” parameter๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์Œ)

----------

function ParamsByRestParameter(...args) {
  return args;
}

// spread syntax ๋„์ž… ์ด์ „, arguments๋กœ ๋น„์Šทํ•˜๊ฒŒ ํ•จ์ˆ˜์˜ ์ „๋‹ฌ์ธ์ž๋“ค์„ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ์Œ.
// arguments: ๋ชจ๋“  ํ•จ์ˆ˜์˜ ์‹คํ–‰์‹œ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ๊ฐ์ฒด
function paramsByArgumentsObj() {
  return arguments;
}

const restParams = ParamsByRestParameter("first", "second", "third");
const argumentsObj = paramsByArgumentsObj("first", "second", "third");

restParams;  // ['first', 'second', 'third']
Object.keys(argumentsObj);   // ['0', '1', '2']
Object.values(argumentsObj); // ['first', 'second', 'third']

restParams === argumentsObj;  // false
typeof restParams;    // 'object'
typeof argumentsObj;  // 'object'
Array.isArray(restParams);   // true
Array.isArray(argumentsObj); // false

const argsArr = Array.from(argumentsObj);  // Array.from(): ๋ฐฐ์—ด๋กœ ์ „ํ™˜

----------

function getAllParams(required1, required2, ...args) {
  return [required1, required2, args];
}

getAllParams(123);  // [123, undefined, []]

10. Destructuring.js (๊ตฌ์กฐ๋ถ„ํ•ดํ• ๋‹น)

// ๊ฐ์ฒด ๋ถ„ํ•ด
const student = { name: "์ตœ์ดˆ๋ณด", major: "๋ฌผ๋ฆฌํ•™๊ณผ" };
const { name, ...args } = student;

name;  // "์ตœ์ดˆ๋ณด"
args;  // { major: "๋ฌผ๋ฆฌํ•™๊ณผ" }

----------

const user = {
  name: "๊น€์ฝ”๋”ฉ",
  company: {
    name: "Kakao",
    department: "Development",
    role: {
      name: "Software Engineer",
    },
  },
  age: 35,
};

const changedUser = {
  ...user,
  name: "๋ฐ•ํ•ด์ปค",
  age: 20,
};

const overwriteChanges = {
  name: "๋ฐ•ํ•ด์ปค",
  age: 20,
  ...user,
};

// result
expect(changedUser).to.eql({
  name: "๋ฐ•ํ•ด์ปค",
  company: {
    name: "Kakao",
    department: "Development",
    role: {
      name: "Software Engineer",
    },
  },
  age: 20,
});

expect(overwriteChanges).to.eql({
  name: "๊น€์ฝ”๋”ฉ",
  age: 35,
  company: {
    name: "Kakao",
    department: "Development",
    role: {
      name: "Software Engineer",
    },
  },
});

// ...user ๊ฐ€ ์–ด๋””์— ์œ„์น˜ํ•ด ์žˆ๋Š”์ง€์— ๋”ฐ๋ผ ๊ฐ์ฒด ๊ฐ’๋“ค์ด ๋‹ฌ๋ผ์ง

0๊ฐœ์˜ ๋Œ“๊ธ€