[JS] js 문법 test
Categories: javascript
📌 개인적인 공간으로 공부를 기록하고 복습하기 위해 사용하는 블로그입니다.
정확하지 않은 정보가 있을 수 있으니 참고바랍니다 :😸
[틀린 내용은 댓글로 남겨주시면 복받으실거에요]
Type
-
Type-2번
1 2 3 4
expect(1 + '1').to.equal(); expect(123 - '1').to.equal(); expect(1 + true).to.equal(); expect('1' + true).to.equal();
- 순서대로 ‘11’, 122, 2 , ‘1true’
- 문자열은 더할 때만 문자로 변환됨.
Scope
-
4번 함수표현식 및 함수선언식
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
let funcExpressed = 'to be a function'; **expect(typeof funcDeclared).to.equal(/*1번*/ ); expect(typeof funcExpressed).to.equal(/*2번*/);** function funcDeclared() { return 'this is a function declaration'; } funcExpressed = function () { return 'this is a function expression'; }; const funcContainer = { func: funcExpressed }; **expect(funcContainer.func()).to.equal(/*3번*/);** funcContainer.func = funcDeclared; **expect(funcContainer.func()).to.equal(/*4번*/);**
- 빈칸 채우기 1번 function, 2번 String 3번 ‘this is a function expression’, 4번 ‘this is a function declaration’
- 1번 위에 선언이 없는데 왜 function인지 이해 안감 expect(typeof funcDeclared).to.equal(‘function’); ⇒ 호이스팅 때문임
- 함수 선언문이 호이스팅되어 맨 위로 끌어올려졌기 때문
- 대조적으로 함수 표현식은 호이스팅되지 않으며, 그 값이 할당된 후에야 비로소 호출 가능함
- function 뒤에 ( )가 있으면 실행하는 것.
- funcContainer.func() , funcContainer의 func()에 해당하는 값은 funExpressed 이고 해당 함수를 호출 하면 ‘this is a function expression’를 반환함.
- funcContainer.func , funcContainer의 func키에 해당하는 값은 funDeclared이고 해당 함수 호출하면 ‘this is a function declaration’를 반환
-
5번 lexical scope와 closure ✨✨✨✨✨✨
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
function a() { let age = 27; let name = 'jin'; let height = 179; **function outerFn() {** let age = 24; name = 'jimin'; let height = 178; **function innerFn() {** age = 26; let name = 'suga'; return height; } innerFn(); **expect(age).to.equal(/*1번*/); expect(name).to.equal(/*2번*/);** // return innerFn; **}** const innerFn = outerFn(); **expect(age).to.equal(/*3번*/); expect(name).to.equal(/*4번*/); expect(innerFn()).to.equal(/*5번*/); }**
- 1번의 경우 코드는 위에서 아래로 흐르고 1번의 제일 근처에 innerFn()이 호출되어 innerFn함수로 가게 됨.
- 여기서 let age=24 였던게 innerFn으로 인해 age=26으로 변경되고
- 2번의 name은 jimin이였다가 suga로 변경되는게 맞지만 suga는 let name으로 새롭게 할당된 변수이므로 innerFn() 안에서만 유효한 값이 므로 변경되지 않음
- 3번 outerFn이 실행되어도 age는 재할당 된것이 아니라 여전히 27
- 4번은 진짜 이해가 안갔는데 마지막에 outerFn()이 실행되었기 때문에 함수스코프가 outerFn()이라서 name=jimin이 됨.
- 5번은 innterFn()에서의 height를 구하는 것이고 outerFn()의 height를 참조
- 1번의 경우 코드는 위에서 아래로 흐르고 1번의 제일 근처에 innerFn()이 호출되어 innerFn함수로 가게 됨.
primitive data type
-
원시형 문제2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
function () { let currentYear = 2020; function afterTenYears(year) { year = year + 10; } afterTenYears(currentYear); **** **expect(currentYear).to.equal(/*1번*/);** function afterTenYears2(currentYear) { currentYear = currentYear + 10; return currentYear; } let after10 = afterTenYears2(currentYear); **expect(currentYear).to.equal(/*2번*/); expect(after10).to.equal(/*3번*/);** }
- 1번 2020, 2번 2020, 3번 2030
- 문제 1에서 afterTenYears(currentYear); 함수가 호출되었지만 let currentYear은 변경되지 않는다, 왜냐면 따로 변수에 할당된 것이 아니라 호출만 되었기 때문
- 문제 2 바로 위처럼 let after10 = afterTenYears2(currentYear); 변수의 선언과 할당이 되어야 함수를 호출하고 실행된 값이 변수에 담긴다
Array
-
slice
1 2 3 4 5 6 7 8 9 10
const arr = ['peanut', 'butter', 'and', 'jelly']; expect(arr.slice(1)).to.deep.equal(['butter', 'and', 'jelly']); expect(arr.slice(0, 1)).to.deep.equal(['peanut']); expect(arr.slice(0, 2)).to.deep.equal(['peanut', 'butter']); expect(arr.slice(2, 2)).to.deep.equal([]); expect(arr.slice(2, 20)).to.deep.equal(['and', 'jelly']); expect(arr.slice(3, 0)).to.deep.equal([]); expect(arr.slice(3, 100)).to.deep.equal(['jelly']); expect(arr.slice(5, 1)).to.deep.equal([]);
- 매개인자 1개만 넣을 경우 : 매개인자에 해당하는 인덱스부터 끝지만 남게 됨 그전은 삭제.
- arr.slice(0) = [‘peanut’, ‘butter’, ‘and’, ‘jelly’] / arr.slice(2) =[ ‘and’, ‘jelly’] / arr.slice(3) =[’jelly’]
- 매개인자 2일 경우 arr.slice(a, b) → index a 부터 b 전까지만 남고 다 잘림.
- a와 b가 같을 경우 빈 배열
- a>b 빈배열
- b가 index범위를 초과하면 a부터 마지막까지만
- 매개인자 1개만 넣을 경우 : 매개인자에 해당하는 인덱스부터 끝지만 남게 됨 그전은 삭제.
-
얕은복사 깊은복사
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
const arr = ['zero', 'one', 'two', 'three', 'four', 'five']; function passedByReference(refArr) { refArr[1] = 'changed in function'; } passedByReference(arr); **//1. expect(arr[1]).to.equal('changed in function');** const assignedArr = arr assignedArr[5] = 'changed in assignedArr'; **//2.** **expect(arr[5]).to.equal('changed in assignedArr');** const copiedArr = arr.slice(); copiedArr[3] = 'changed in copiedArr'; **//3.** **expect(arr[3]).to.equal('three');**
Array를 함수의 전달인자로 전달할 경우, reference가 전달=얕은복사
- 코드에서 1번의 경우 바로 위에서 passedByReference()함수에 매개인자로 arr이 들어가므로 arr = [‘zero’, ‘‘changed in function’’, ‘two’, ‘three’, ‘four’, ‘five’]; 로 변경됨.
- 코드 2번의 경우 const assignedArr = arr을 통해 얕은 복사가 이루어지고 assignedArr와 arr은 같은 주소 값을 가지게 됨
- 그러므로 assignedArr[5] = ‘changed in assignedArr’; 에 의해 assignedArr의 5번 인덱스가 변경되었으므로 arr도 동일하게 변경됨
- 현재 arr와 assigedArr은 배열 → [‘zero’, ‘‘changed in function’’, ‘two’, ‘three’, ‘four’, ‘changed in assignedArr’]
- 코드 3번의 경우 const copiedArr = arr.slice();는 다른 주소 값을 가지게 되고
- copiedArr[3] = ‘changed in copiedArr’;을 인해 copiedArr [‘zero’, ‘‘changed in function’’, ‘two’, ‘changed in copiedArr’, ‘four’, ‘changed in assignedArr’]를 가지고
- arr = [‘zero’, ‘‘changed in function’’, ‘two’, ‘three’, ‘four’, ‘changed in assignedArr’]을 가지게 됨.
Object
-
기본
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
const emptyObj = {}; expect(typeof emptyObj === 'object').to.equal(true); expect(emptyObj.length).to.equal(undefined); const megalomaniac = { mastermind: 'Joker', henchwoman: 'Harley', getMembers: function () { return [this.mastermind, this.henchwoman]; }, relations: ['Anarky', 'Duela Dent', 'Lucy'], twins: { 'Jared Leto': 'Suicide Squad', 'Joaquin Phoenix': 'Joker', 'Heath Ledger': 'The Dark Knight', 'Jack Nicholson': 'Tim Burton Batman', }, }; expect(megalomaniac.length).to.equal(undefined); expect(megalomaniac.mastermind).to.equal('Joker'); expect(megalomaniac.henchwoman).to.equal('Harley'); expect(megalomaniac.henchWoman).to.equal(undefined); expect(megalomaniac.getMembers()).to.deep.equal(['Joker','Harley']); expect(megalomaniac.relations[2]).to.equal('Lucy'); expect(megalomaniac.twins['Heath Ledger']).to.deep.equal('The Dark Knight');
- 깊게 볼 건 없고 금방 풀 수 있는 문제.
- 객체.length는 길이를 구하는게 아닌 length라는 키로 값을 구하는 것임.
- 그리고 객체는 length를 메서드가 없음
- 객체의 총 entryset을 알고 싶다면 전체 키를 배열로 받아서 배열의 길이를 구할 수 있음.
-
Object를 함수의 전달인자로 전달할 경우, reference가 전달 ✨✨
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
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', }, }; function passedByReference(refObj) { refObj.henchwoman = 'Adam West'; } passedByReference(obj); **//문제1** **expect(obj.henchwoman).to.equal('Adam West');** const assignedObj = obj; assignedObj['relations'] = [1, 2, 3]; **//문제2** **expect(obj['relations']).to.deep.equal([1, 2, 3]);** const copiedObj = Object.assign({}, obj); copiedObj.mastermind = 'James Wood'; **//문제3** **expect(obj.mastermind).to.equal('Joker');** obj.henchwoman = 'Harley'; **//문제4** **expect(copiedObj.henchwoman).to.equal('Adam West');** delete obj.twins['Jared Leto']; **//문제5** **expect('Jared Leto' in copiedObj.twins).to.equal(false);**
- 문제 1의 바로 위에서 passedByReference(obj);가 실행되었고 henchwoman = ‘Adam West’;으로 값이 변경됨.
-
변경 후
1 2 3 4 5 6 7 8 9 10 11
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', }, }
-
- 문제 2의 위에서 const assignedObj = obj;가 실행되었고 얕은복사가 이루어짐 결국 같은 주소 값을 가지게됨
- assignedObj[‘relations’] = [1, 2, 3]; 로 인해 relation 값이 변경되어 obj의 값도 변경됨
- 문제 3에서 const copiedObj = Object.assign({}, obj); 가 이루어졌고 이것은 다른 주소 값을 가지는 깊은 복사가 이루어짐.(단 객체 내의 객체는 같은 주소 값을 가지게 됨)
- 문제 4에서 obj의 henchwoman키의 값이 변경되었지만 copiedObj의 값은 변경되지 않았음
- 문제 5에서 obj.twins내 Jared Leto의 키와 값이 delete되었고 copiedObj내 객체는 같은 주소 값을 가지게 된다. 객체 내의 객체까지는 깊은 복사가 이루어지지 않음.. 결국 obj에서 삭제될 때 같이 삭제되었으므로 twins 객체의 Jared Leto의 키와 값은 존재하지 않으므로 false이다.
### Destructing
-
객체 덮어쓰기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
const user = { name: '김코딩', company: { name: 'Javascript', department: 'Development', role: { name: 'Software Engineer' } }, } const changedUser = { ...user, name: '박해커', age: 20 } const overwriteChanges = { name: '박해커', age: 20, ...user } const changedDepartment = { ...user, company: { ...user.company, department: 'Marketing' } }
-
changedUser
1
{name: '박해커',**company: {name: 'Javascript',department: 'Development',role:{ name: 'Software Engineer'}}**,age: 20}
-
왜 …user가 먼저 나오는데 name:박해커 와 age:20 사이에 들어오는지?
-
...user
는user
객체의 모든 속성을 복사1 2 3 4 5 6 7 8 9
{name: '김코딩', company: { name: 'Javascript', department: 'Development', role: { name: 'Software Engineer' } } }
그 다음,
name: '박해커'
속성이 추가됨. 기존의name
속성이 ‘김코딩’이었지만, 이제 ‘박해커’로 덮어씀1 2 3 4 5 6 7 8 9
{name: '박해커', company: { name: 'Javascript', department: 'Development', role: { name: 'Software Engineer' } } }
마지막으로, 새로운
age: 20
속성이 추가됩니다1 2 3 4 5 6 7 8 9 10
{name: '박해커', company: { name: 'Javascript', department: 'Development', role: { name: 'Software Engineer' } }, age: 20 }
-
-
-
overwriteChanges
1
{name: '김코딩',age: 20, company: {name: 'Javascript',department: 'Development', role: { name: 'Software Engineer' }}}
-
changedDepartment
1
{name: '김코딩', company:{name: 'Javascript', department: 'Marketing', role: {name: 'Software Engineer'}},}
- 문제 1의 바로 위에서 passedByReference(obj);가 실행되었고 henchwoman = ‘Adam West’;으로 값이 변경됨.
Comment
이것 보다 훨씬 문제가 많았는데 보느라 목이랑 눈이 빠질 것 같다.
js java랑 비슷한데?? 쉬운데 ? 하고 만만하게 보다가 큰코다쳤다. 정말..
분명 다 안다고 생각했는데 막상 문법 테스트 푸는데 내가 이렇게 모르는 것이 많았나 생각이 들고
Scope랑 Destructing은 아직 겉만 이해한 것 같고 깊게 이해하지는 못한 것 같다.
오늘은 다 이해 했으니 내일 풀이 듣고 다시 복습해야지
Leave a comment