it("Object를 함수의 전달인자로 전달할 경우, reference가 전달됩니다.", function () {
const obj = {
mastermind: "Joker",
henchwoman: "Harley",
relations: ["Anarky", "Duela Dent", "Lucy"],
twins: {
"Jared Leto": "Suicide Squad",
"Joaquin Phoenix": "Joker",
"Heath Ledger": "The Dark Knight",
"Jack Nicholson": "Tim Burton Batman",
},
};
const copiedObj = Object.assign({}, obj);
delete obj.twins["Jared Leto"];
// expect("Jared Leto" in copiedObj.twins).to.equal(1️⃣);
});
});
1️⃣에 들어갈 단어는 true인가 false인가??
깊은 복사와 얕은 복사를 나름 열심히 공부했다고 생각했는데 막상 이런 문제를 만나니까 깊게 생각 못하고 오답을 냈다.
it("Rest Parameter는 함수의 전달인자를 배열로 다룰 수 있게 합니다.", function () {
// rest parameter는 spread syntax를 통해 간단하게 구현됩니다.
function getAllParamsByRestParameter(...args) {
return args;
}
// arguments를 통해 '비슷하게' 함수의 전달인자들을 다룰 수 있습니다. (spread syntax 도입 이전)
// arguments는 모든 함수의 실행 시 자동으로 생성되는 '객체'입니다.
function getAllParamsByArgumentsObj() {
return arguments;
}
const restParams = getAllParamsByRestParameter("first", "second", "third");
const argumentsObj = getAllParamsByArgumentsObj("first", "second", "third");
expect(restParams).to.deep.equal(["first", "second", "third"]);
expect(Object.keys(argumentsObj)).to.deep.equal(1️⃣);
expect(Object.values(argumentsObj)).to.deep.equal(2️⃣);
// arguments와 rest parameter를 통해 배열로 된 전달인자(args)의 차이를 확인하시기 바랍니다.
expect(restParams === argumentsObj).to.deep.equal(false);
expect(typeof restParams).to.deep.equal("object");
expect(typeof argumentsObj).to.deep.equal(3️⃣);
expect(Array.isArray(restParams)).to.deep.equal(true);
expect(Array.isArray(argumentsObj)).to.deep.equal(4️⃣);
const argsArr = Array.from(argumentsObj);
expect(Array.isArray(argsArr)).to.deep.equal(true);
expect(argsArr).to.deep.equal(5️⃣);
expect(argsArr === restParams).to.deep.equal(false);
});
막상 풀 때 arguments 객체를 떠올리지 못해서 시간이 좀 걸렸던 문제이다. arguments 객체에 대한 이해가 있으면 어렵지 않게 풀 수 있다.
모든 인수는 매개변수의 숫자와는 무관하게 암묵적으로 arguments 객체의 프로퍼티로 보존된다. 살짝 극단적으로 매개변수는 0개이고 인수가 100개이면 모두 arguments 객체의 프로퍼티로 보존되는 것이다.
arguments 객체의 value : 인수들
arguments 객체의 key : 인수의 순서(0부터 시작)
arguments 객체는 length property도 가진다. 인수의 개수를 의미한다.
이거 배열 아냐?? arguments 객체는 유사 배열 객체이다.
참고: arguments 객체는 배열 형태로 인자 정보를 갖고 있지만 실제 배열이 아닌 유사배열 객체다. 유사배열 객체란, length 프로퍼티를 가지고 for문으로 순회할 수 있는 객체를 의미한다.
그렇다면 문제에서 의미하는 arguments도 arguments 객체가 된다.
function getAllParamsByArgumentsObj() {
return arguments;
}
const argumentsObj = getAllParamsByArgumentsObj("first", "second", "third");
console.log(argumentsObj); // arguments 객체 출력
이제 문제로 돌아와보자.
1️⃣
expect(Object.keys(argumentsObj)).to.deep.equal(1️⃣);
arguments 객체의 키만 뽑아내서 배열로 만든다면?
['0','1','2']가 될 것이다. (string type임을 주의!!)
2️⃣
expect(Object.values(argumentsObj)).to.deep.equal(2️⃣);
같은 이유로 values만 뽑아내서 배열로 만들면
['first', 'second', 'third']가 될 것이다.
3️⃣
expect(typeof argumentsObj).to.deep.equal(3️⃣);
arguments 객체는 유사배열'객체'이고, type은 object이다.
따라서 정답은 "object"
4️⃣
expect(Array.isArray(argumentsObj)).to.deep.equal(4️⃣);
3️⃣과 같은 맥락으로, 유사배열 객체는 배열이 아닌 객체이므로,
정답은 false
5️⃣
const argsArr = Array.from(argumentsObj);
expect(argsArr).to.deep.equal(5️⃣);
이 문제의 핵심은 Array.from()에 인수로 유사배열 객체를 전달했을 때 무엇이 반환되느냐이다.
무엇이 반환되냐구? values로 이루어진 배열을 반환한다.
따라서 정답은
["first", "second", "third"]
이다.
자바스크립트를 빈칸 채우기로 접근해보니 좀 더 확실하게 내 지식으로 만들 수 있는 것 같아서 의미있는 시간이었다.