์ฝ์ค ์์ ํ ์ฒซ Koans! ๋ญ๊ฐ ์ ๊ธฐํ๊ณ ์ฌ๋ฐ์๋ค...!
๊ฒ์ ํ์คํธ๋ฅผ ๊นจ๋๊ฐ๋ ๊ฒ๋ ๊ฐ์์, ๋นจ๊ฐ ๊ธ์จ๊ฐ ์ด๋ก์์ผ๋ก ๋ฐ๋ ๋ ๋ง๋ค ์ง๋ฆฟํ๋ค.
์ค๋์ ๋ฒจ๋ก๊ทธ๋ JavaScript Koans๋ฅผ ํ๋ฉด์ ํท๊ฐ๋ ธ๋ ๋ถ๋ถ์ด๋, ์๋ก์ด ์๊ฒ๋ ๋ถ๋ถ์ ์ ๋ฆฌํด ๋ดค๋ค! ์์ฃผ์์ฃผ ๋ค์ด์์ ๋ค์ ๋ณด๋ฉด์ ์์ ํ ๋ด๊ฒ์ผ๋ก ๋ง๋ค์!!
expect(1 + "1").to.equal("11"); expect(123 - "1").to.equal(122); expect(1 + true).to.equal(2); expect("1" + true).to.equal("1true");
์ ์์๋ค ์ฒ๋ผ JS์๋ ๋ค์ ์ดํดํ๊ธฐ ํ๋ ๋ถ๋ถ๋ค์ด ์กด์ฌํ๋ค.
์ด๋ฐ ๋ณ๋(quirky) ๋ถ๋ถ๋ค์ ๋ฐ๋ก ๋ชจ์ ๋ ์ ์ฅ์๊ฐ ๋ฐ๋ก ์์์ ๋!
์ด๋ฐ ๋ณ๋ ํน์ฑ๋ค์ ์ ๋ถ ์๊ธฐํด์ ๋์ํ๋ ค ํ์ง ๋ง๊ณ , ์ฌ๋ฐ๋ฅธ ์ฝ๋ฉ ์ต๊ด์ ๊ธฐ๋ฅด์. ์ต๋ํ ๊ฐ์ ํ์
๋ผ๋ฆฌ ์ฐ์ฐ์ ํ๊ณ , ์ฆ ์๊ฒฉํ ๋์น ์ฐ์ฐ(===
)์ ์ฌ์ฉํ๊ณ , ์กฐ๊ฑด๋ฌธ์ ๋น๊ต ์ฐ์ฐ์ ๋ช
์ํ์.
์๋ฐ์คํฌ๋ฆฝํธ์์ ์์ ์๋ฃํ(primitive data type ๋๋ ์์๊ฐ)์
๊ฐ์ฒด๊ฐ ์๋๋ฉด์ method๋ฅผ ๊ฐ์ง์ง ์๋ ์๋ 6๊ฐ์ง์ ๋ฐ์ดํฐ
โก string, number, bigint, boolean, undefined, symbol, (null)
์์ ์๋ฃํ์ ๊ฐ ์์ฒด์ ๋ํ ๋ณ๊ฒฝ์ด ๋ถ๊ฐ๋ฅ(immutable)
์๋ก์ด ๊ฐ์ผ๋ก ์ฌํ ๋น์ ๊ฐ๋ฅํ๋ค!
์์ ์๋ฃํ์ ๋ณ์์ ํ ๋นํ ๊ฒฝ์ฐ, ๊ฐ ์์ฒด์ ๋ณต์ฌ๊ฐ ์ผ์ด๋๋ค.
โก ์ฆ, ์ฃผ์๊ฐ ์๋๋ผ ๊ฐ ์์ฒด๋ฅผ ๋ณต์ฌํด์ ์์ ์๋ก์ด ๋ณ์์ ํ ๋นํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋ณ์์ ๊ฐ์ ๋ณ๊ฒฝํด๋ ์๋ณธ ์์ ์๋ฃํ์ ๊ฐ์ ๋ณํ์ง ์๋๋ค.
์์ ์๋ฃํ ๋๋ ์์ ์๋ฃํ์ ๋ฐ์ดํฐ๋ฅผ ํจ์์ ์ ๋ฌ์ธ์๋ก ์ ๋ฌํ ๊ฒฝ์ฐ๋ ๊ฐ ์์ฒด์ ๋ณต์ฌ
์๋ฐ์คํฌ๋ฆฝํธ์์ ์์ ์๋ฃํ์ด ์๋ ๋ชจ๋ ๊ฒ์ ์ฐธ์กฐ ์๋ฃํ.
๋ฐฐ์ด([]
)๊ณผ ๊ฐ์ฒด({}
), ํจ์(function(){}
)๊ฐ ๋ํ์
์ฐธ์กฐ ์๋ฃํ์ ๋ณ์์ ํ ๋นํ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ์ ์ฃผ์๊ฐ ์ ์ฅ
๋ฐฐ์ด์ด ์ผ๋ง๋ ๋ง์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋์ง๊ฐ ํ๋ก๊ทธ๋จ์ ์คํ ์ค ์์๋ก ๋ณ๊ฒฝ๋ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฐ๋ก ๋ช ์ํ์ง ์๋ ์ด์ 100๋ง๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ผ์ผํ ๋ณต์ฌํ๋ ๊ฒ์ ์๋นํ ๋นํจ์จ์ ์ด๋ค. ๋ฐ๋ผ์ ์ผ๋จ์ ์ฃผ์๋ง ๋ณต์ฌํด์ ๋์ผํ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ผ๋ณด๊ฒ ๋ง๋๋ ๊ฒ์ด ํจ์จ์ ์ด๋ค.
arr.slice
๋ arr
์ ๊ฐ ์์ฒด๋ฅผ ๋ณต์ฌํ์ฌ ์๋ก์ด ๋ฐฐ์ด์ ๋ฆฌํด
๊ฐ์ฒด(Object)๋ฅผ ํจ์์ ์ ๋ฌ์ธ์๋ก ์ ๋ฌํ ๊ฒฝ์ฐ, ์ฃผ์(reference)๊ฐ ์ ๋ฌ๋๋ค.
'Object.assign'์ ํตํ ๋ณต์ฌ๋ reference variabled์ ์ฃผ์๋ง ๋ณต์ฌ
์ฆ, ๊ทธ ์์ ์๋ ๋ ๋ค๋ฅธ ๊ฐ์ฒด๋ ๋ณต์ฌํ์ง ์๋๋ค. (์์๋ณต์ฌ์ ๊น์ ๋ณต์ฌ)
Array.from = ์ ์ฌ๋ฐฐ์ด ๊ฐ์ฒด๋ฅผ ๋ฐฐ์ด๋ก ๋ฐ๊ฟ์ค๋ค.
undefined
์ด๋ค. let funcExpressed = "to be a function"; expect(typeof funcDeclared).to.equal("function"); expect(typeof funcExpressed).to.equal("string"); //ํจ์ ์ ์ธ๋ฌธ์ผ๋ก ์ ์๋ ํจ์๋ ํธ์ด์คํ ์ด ์ผ์ด๋ ๊ฒ ์ฒ๋ผ ๋ณด์ธ๋ค. //๋ฐ์ ์ ์ธ ํ๋๋ฐ๋ ์์์๋ ์กฐํ ๋ฐ ์ฌ์ฉ๊ฐ๋ฅ function funcDeclared() { return "this is a function declaration"; } //ํจ์ ํํ์์ผ๋ก ์ ์๋ ํจ์๋ ํธ์ด์คํ ์ด ์ผ์ด๋์ง ์๋๋ค. //๋ฐ๋ผ์ ์๋จ typeof ์ฝ๋๋ string์ด ๋์จ๋ค. funcExpressed = function () { return "this is a function expression"; };
let message = "Outer"; function getMessage() { //ํจ์ ๋ด๋ถ์ message๊ฐ ์๋? // ์์ผ๋ฉด ์ธ๋ถ์ฐธ์กฐ return message; } function shadowGlobal() { //ํจ์ ๋ด๋ถ์ massage๊ฐ ์๋? // ์์ผ๋ ๋ด๋ถ ์ฐธ์กฐ let message = "Inner"; return message; } function shadowGlobal2(message) { //๋งค๊ฐ๋ณ์๊ฐ ์์ผ๋, ๋งค๊ฐ๋ณ์ ์ฐธ์กฐ return message; } function shadowParameter(message) { //์ธ๋ถ ๋ณ์์ ์ฌํ ๋น ๋๋ค. // ํ๋ผ๋ฏธํฐ๋ฅผ ์ธ๋ถ๋ก ์ ๋ฌ๋๋๋ก ํด๋๊ณ ์ ๊ตณ์ด ๋ด๋ถ์์ ์ฌํ ๋น? ์ด๋ฌ์ง ๋ง์. message = "Do not use parameters like this!"; return message; } expect(getMessage()).to.equal("Outer"); expect(shadowGlobal()).to.equal("Inner"); expect(shadowGlobal2("Parameter")).to.equal("Parameter"); expect(shadowParameter("Parameter")).to.equal( "Do not use parameters like this!" );
- ํจ์ ์์์ ๋ค์
let
์ผ๋ก ์ ์ธํ๋ฉด ๊ทธ๋ ๊ฒ ์๋ก ์ ์ธ๋ ๋ณ์๊ฐ ํจ์ ์์์ ํ์ฉ ๊ฐ๋ฅ. ์๋ ๊ฒ ์กฐ๋ ๊ฒ ํ์ฉํ ๊ฐ์, ๋ฆฌํด ๊ฐ์ผ๋ก ๋๊ฒจ์ค ์๋ ์๋ค.- ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํด๋ ๋์ผํ๊ฒ ๊ฐ๋ฅ!
const htmlMaker = (tag) => (textContent) => `<${tag}>${textContent}</${tag}>`; expect(htmlMaker("div")("code states")).to.eql("<div>code states</div>");
- html ํ๊ทธ ๊ฐ์ ๋ง๋๋ JS ์ฝ๋๋ฅผ ํ์ดํ ํจ์๋ก ์์ฑํ ๊ฒ.
this
๊ฐ ์๋ค.this
๋ฅผ ์ฐพ์ ๋, ํ์ดํ ํจ์ ๋ฐ๋ก ๋ฐ๊นฅ ๋ฒ์์์ this
๋ฅผ ์ฐพ๊ฒ ๋๋ค. // rest parameter๋ ํญ์ ๋ฐฐ์ด
function getAllParams(required1, required2, ...args) {
return [required1, required2, args];
}
expect(getAllParams(123)).to.deep.equal([123, undefined, []]);
const array = ["code", "states", "im", "course"];
const [first, second] = array;
expect(first).to.eql("code");
expect(second).to.eql("states");
const result = [];
function foo([first, second]) {
result.push(second);
result.push(first);
}
foo(array);
expect(result).to.eql(["states", "code"]);
const array = ["code", "states", "im", "course"];
const [start, ...rest] = array;
expect(start).to.eql("code");
expect(rest).to.eql(["states", "im", "course"]);
// ๋ค์๊ณผ ๊ฐ์ ๋ฌธ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค.
//ํ ๋นํ๊ธฐ ์ ์ผ์ชฝ์๋, rest ๋ฌธ๋ฒ ์ดํ์ ์ผํ๊ฐ ์ฌ ์ ์๋ค!
// const [first, ...middle, last] = array
const name = "๊น์ฝ๋ฉ";
const age = 28;
const person = {
name,
age,
level: "Junior",
};
expect(person).to.eql({ name: "๊น์ฝ๋ฉ", age: 28, level: "Junior" });
const student = { name: "๋ฐํด์ปค", major: "๋ฌผ๋ฆฌํ๊ณผ" };
const { name } = student;
expect(name).to.eql("๋ฐํด์ปค");
const user = {
name: "๊น์ฝ๋ฉ",
company: {
name: "Code States",
department: "Development",
role: {
name: "Software Engineer",
},
},
age: 35,
};
const changedUser = {
...user,
name: "๋ฐํด์ปค",
age: 20,
};
const overwriteChanges = {
name: "๋ฐํด์ปค",
age: 20,
...user,
};
//spread syntax๋ก user๋ฅผ ๋ถ๋ฌ์ค๊ธฐ ์ ์ name๊ณผ age์ ๊ฐ์ ๋ถ์ฌํด์
//๋ถ๋ฌ์ค๋ฉด ๋ค์ ์๋ณธ user์ ๊ฐ์ผ๋ก ๋ฎ์ด์์์ง๋ค.
const changedDepartment = {
...user, //์๋ณธ user ๊ฐ ๋ถ๋ฌ์ด
company: {
...user.company, //์๋ณธ user์ company ๊ฐ ๋ถ๋ฌ์ด
department: "Marketing", //๋ถ๋ฌ์จ ๊ฐ ์ค, department ๋ถ๋ถ ๊ฐ ๋ณ๊ฒฝ
},
};
expect(changedUser).to.eql({
name: "๋ฐํด์ปค",
company: {
name: "Code States",
department: "Development",
role: {
name: "Software Engineer",
},
},
age: 20,
});
expect(overwriteChanges).to.eql({
name: "๊น์ฝ๋ฉ",
company: {
name: "Code States",
department: "Development",
role: {
name: "Software Engineer",
},
},
age: 35,
});
expect(changedDepartment).to.eql({
name: "๊น์ฝ๋ฉ",
company: {
name: "Code States",
department: "Marketing",
role: {
name: "Software Engineer",
},
},
age: 35,
});