Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 혼공학습단
- 혼자서공부하는네트워크
- UI
- 2024년회고
- 혼자서공부하는
- user flow
- 제이콥닐슨 사용성평가기준
- HTTP
- 혼공시리즈
- 혼자공부하는네트워크
- column grid system
- https
- GUI
- 프로그래머스문자열출력하기
- HTTP메시지구조
- 혼공네트
- 피터모빌의벌집모형
- 자바스크립트문자열출력하기
- 혼자서공부하는얄팍한코딩지식
- 사이드이펙
- 혼공얄코
- 이더넷허브
- 혼자공부하는얄팍한코딩지식
- 네트워크
- HTTP와HTTPS차이점
- 혼공학습단11기
- 혼공네트워크
- 혼자공부하는
- 한빛미디어
- UX
Archives
- Today
- Total
호기심으로 시작한 Frontend 꾸준함으로 채워나가는 Developer
[JavaScript] Koans 본문
Koans
JS 02. Types-part1
expect의 전달인자로 들어간 표현식의 평가(evaluation) 결과를 예측해 봅니다.
it('expect의 전달인자로 들어간 표현식의 평가(evaluation) 결과를 예측해 봅니다.', function () {
expect(1 + '1').to.equal('11');
});
it('expect의 전달인자로 들어간 표현식의 평가(evaluation) 결과를 예측해 봅니다.', function () {
expect(123 - '1').to.equal(122);
});
it('expect의 전달인자로 들어간 표현식의 평가(evaluation) 결과를 예측해 봅니다.', function () {
expect(1 + true).to.equal(**2**);
});
**//true= 숫자로 1, false= 숫자로 0**
it('expect의 전달인자로 들어간 표현식의 평가(evaluation) 결과를 예측해 봅니다.', function () {
expect('1' + true).to.equal('1true');
});
JS 03. LetConst
it("'const'로 선언된 객체의 경우, 속성을 추가하거나 삭제할 수 있습니다.", function () {
const obj = { x: 1 };
expect(obj.x).to.equal(1);
delete obj.x;
expect(obj.x).to.equal(**undefined**);
// 여전히 재할당은 금지됩니다.
// obj = { x: 123 };
obj.occupation = 'SW Engineer';
expect(obj['occupation']).to.equal('SW Engineer');
});
JS 04. Scope
함수 호이스팅 (hoisting)
it('lexical scope에 대해서 확인합니다.', function () {
let message = 'Outer';
function getMessage() {
return message;
}
function shadowGlobal() {
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!");
expect(message).to.equal(**"Outer"**);
});
클로저(closure)
it('클로저(closure)에 대해 확인합니다.', function () {
function increaseBy(increaseByAmount) {
return function (numberToIncrease) {
return numberToIncrease + increaseByAmount;
};
}
const increaseBy3 = increaseBy(3);
const increaseBy5 = increaseBy(5);
expect(increaseBy3(10)).to.equal(13);
expect(increaseBy5(10)).to.equal(15);
expect(increaseBy(8)(6) + increaseBy(5)(9)).to.equal(28);
});
- MDN 클로저의 정의
- Closures - JavaScript | MDN
<aside> ✔️ lexical scope 와 closure에 대해 다시 확인하기!!
</aside>
it('lexical scope와 closure에 대해 다시 확인합니다.', function () {
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(26);
expect(name).to.equal("jimin");
return innerFn;
}
const innerFn = outerFn();
expect(age).to.equal(27);
expect(name).to.equal("jimin");
expect(innerFn()).to.equal(178)
});
});
JS 06. Types-part2
const ages = [22, 23, 27];
allowedToDrink = ages;
expect(allowedToDrink === ages).to.equal(true);
expect(allowedToDrink === [22, 23, 27]).to.equal(**false**);
const nums1 = [1, 2, 3];
const nums2 = [1, 2, 3];
expect(nums1 === nums2).to.equal(**false**);
/*
배열 nums1과 배열 num2에는 동일한 데이터 [1, 2, 3]이 들어있는 게 분명해 보이는데, 이 둘은 같지가 않습니다.
사실 변수 num1와 num2는 배열이 아닙니다.
참조 타입의 변수에는 (데이터에 대한) 주소만이 저장된다는 것을 떠올려 봅시다.
정확히 말해서 변수 num1은 데이터 [1, 2, 3]이 저장되어 있는 메모리 공간(heap)을 가리키는 주소를 담고 있습니다.
따라서 위의 코드는 각각 다음의 의미를 가지고 있습니다.
const nums1 = [1, 2, 3]; // [1, 2, 3]이 heap에 저장되고, 이 위치의 주소가 변수 num1에 저장된다.
const nums2 = [1, 2, 3]; // [1, 2, 3]이 heap에 저장되고, 이 위치의 주소가 변수 num2에 저장된다.
이제 heap에는 두 개의 [1, 2, 3]이 저장되어 있고, 각각에 대한 주소가 변수 num1, num2에 저장되어 있습니다.
이게 비효율적으로 보일수도 있습니다. 굳이 같은 데이터를 왜 한번 더 저장하는 지 이해하기란 쉽지 않습니다. */
JS 07. Array
it('Array의 기본을 확인합니다.', function () {
const emptyArr = [];
expect(typeof emptyArr === 'array').to.equal(false);
expect(emptyArr.length).to.equal(0);
it('Array 메소드 slice를 확인합니다.', function () {
const arr = ['peanut', 'butter', 'and', 'jelly'];
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([]);
expect(arr.slice(0)).to.deep.equal(['peanut', 'butter', 'and', 'jelly']);
});
it('Array를 함수의 전달인자로 전달할 경우, reference가 전달됩니다.', function () {
// call(pass) by value와 call(pass) by reference의 차이에 대해서 학습합니다.
const arr = ['zero', 'one', 'two', 'three', 'four', 'five'];
const copiedArr = arr.slice();
copiedArr[3] = 'changed in copiedArr';
expect(arr[3]).to.equal( 'three', 'four', 'five');
});
JS 08. Object
it('Object의 기본을 확인합니다.', function () {
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'],
}
expect(megalomaniac.length).to.equal(**undefined**);
/* 보통의 배열의 경우 .length 를 사용하여 길이값을 구할 수 있다.
하지만 객체의 경우 Object.keys를 사용하여 구할 수 있다.
Object.keys([객체명].values).length /*
it("'this'는 method를 호출하는 시점에 결정됩니다.", function () {
const currentYear = new Date().getFullYear();
const megalomaniac = {
mastermind: 'James Wood',
henchman: 'Adam West',
birthYear: 1970,
calculateAge: function (currentYear) {
return currentYear - this.birthYear;
},
changeBirthYear: function (newYear) {
this.birthYear = newYear;
},
};
expect(currentYear).to.equal(2022);
expect(megalomaniac.calculateAge(currentYear)).to.equal(52);
megalomaniac.birthYear = 2000;
expect(megalomaniac.calculateAge(currentYear)).to.equal(22);
megalomaniac.changeBirthYear(2010);
expect(megalomaniac.calculateAge(currentYear)).to.equal(12);
});
더보기
* !!Advanced [this.mastermind]? this.birthYear? this가 무엇일까요?
*
* method는 '어떤 객체의 속성으로 정의된 함수'를 말합니다. 위의 megalomaniac 객체를 예로 든다면,
* getMembers는 megalomaniac 객체의 속성으로 정의된 함수인 '메소드'라고 할 수 있습니다. megalomaniac.getMembers()와 같은 형태로 사용(호출)할 수 있죠.
* 사실은, 전역 변수에 선언한 함수도 웹페이지에서 window 객체의 속성으로 정의된 함수라고 할 수 있습니다.
* window. 접두사 없이도 참조가 가능하기 때문에(window.foo()라고 사용해도 됩니다.), 생략하고 쓰는 것뿐입니다. 이렇듯, method는 항상 '어떤 객체'의 method입니다.
* 따라서 호출될 때마다 어떠한 객체의 method일 텐데, 그 '어떠한 객체'를 묻는 것이 this입니다.
* 예시로, obj이라는 객체 안에 foo라는 메서드를 선언하고, this를 반환한다고 했을 때 ( 예: let obj = {foo: function() {return this}}; )
* obj.foo() === obj 이라는 코드에 true라고 반환할 것입니다.
* this는 함수의 호출에 따라서 값이 달라지기도 합니다. (apply나 call, bind에 대해서는 하단의 학습자료를 통해 더 공부해 보세요.)
*
* 그러나 화살표 함수는 다릅니다. 자신의 this가 없습니다.
* 화살표 함수에서의 this는 자신을 감싼 정적 범위(lexical context)입니다. (전역에서는 전역 객체를 가리킵니다.)
* 일반 변수 조회 규칙(normal variable lookup rules)을 따르기 때문에, 현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수 바로 바깥 범위에서 this를 찾습니다.
* 그렇기에 화살표 함수를 사용할 때, 이러한 특이점을 생각하고 사용해야 합니다.
*/
*
* method는 '어떤 객체의 속성으로 정의된 함수'를 말합니다. 위의 megalomaniac 객체를 예로 든다면,
* getMembers는 megalomaniac 객체의 속성으로 정의된 함수인 '메소드'라고 할 수 있습니다. megalomaniac.getMembers()와 같은 형태로 사용(호출)할 수 있죠.
* 사실은, 전역 변수에 선언한 함수도 웹페이지에서 window 객체의 속성으로 정의된 함수라고 할 수 있습니다.
* window. 접두사 없이도 참조가 가능하기 때문에(window.foo()라고 사용해도 됩니다.), 생략하고 쓰는 것뿐입니다. 이렇듯, method는 항상 '어떤 객체'의 method입니다.
* 따라서 호출될 때마다 어떠한 객체의 method일 텐데, 그 '어떠한 객체'를 묻는 것이 this입니다.
* 예시로, obj이라는 객체 안에 foo라는 메서드를 선언하고, this를 반환한다고 했을 때 ( 예: let obj = {foo: function() {return this}}; )
* obj.foo() === obj 이라는 코드에 true라고 반환할 것입니다.
* this는 함수의 호출에 따라서 값이 달라지기도 합니다. (apply나 call, bind에 대해서는 하단의 학습자료를 통해 더 공부해 보세요.)
*
* 그러나 화살표 함수는 다릅니다. 자신의 this가 없습니다.
* 화살표 함수에서의 this는 자신을 감싼 정적 범위(lexical context)입니다. (전역에서는 전역 객체를 가리킵니다.)
* 일반 변수 조회 규칙(normal variable lookup rules)을 따르기 때문에, 현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수 바로 바깥 범위에서 this를 찾습니다.
* 그렇기에 화살표 함수를 사용할 때, 이러한 특이점을 생각하고 사용해야 합니다.
*/
'Codestates 부트캠프 > Section01 - TIL' 카테고리의 다른 글
Git - Local Git repository & Remote Git repository (0) | 2022.07.19 |
---|---|
TIL- 원시 자료형과 참조 자료형 (0) | 2022.07.11 |
Unit5 - [CSS] 기초 (0) | 2022.06.30 |
Unit2. [JavaScript] 기초 - 변수, 타입, 함수 (0) | 2022.06.29 |
Unit2. [JavaScript] 기초 (0) | 2022.06.24 |