오늘도 끄적끄적

느리더라도 꾸준하게

자바스크립트에서 this는 상황에 따라 다른 값을 반환해서 아주 짜증나기 마련이다.
이와 관련해서 하나하나 낱낱이 테스트해보자.

ES5

함수로서 호출할 때

1
2
3
4
5
6
7
'use strict';
var a = function() { // 함수로서 호출할 때
// strict mode에서는 undefined
// non-strict mode에서는 Window
console.log(this);
};
a();
더 읽어보기 »

우리는 주로 ~라는 문자를 물결이라고 읽었다.
하지만 영어권 국가에서는 Tilde(틸드)라고 읽는다.
따라서 해당 연산자를 틸드 연산자라고 부른다.
해당 연산자가 기본적으로 어떤 일을 하는지 보자.

뭐하는 놈이니?

~ 연산자는 비트 단위의 연산자이다.
즉, 10진수를 2진수로 바꿔버린 후 연산을 진행한다는 것이다.
비트 단위의 연산자 중에 Not을 진행하는 연산자이다.
Not 연산자이므로 단항 연산자이다.
간단하게 어떻게 작동하는지 보자.

1
console.log(~1); // -2
더 읽어보기 »

생성자(Constructor)

인스턴스가 생성될 때 호출되는 인스턴스 초기화 메소드
인스턴스 변수 초기화 작업에 주로 사용된다.

생성자는 인스턴스를 생성하지 못한다!

나는 생성자로 인스턴스를 생성하고
new 연산자가 C언어의 &(주소값 반환) 역할을 하는 줄 알았는데
new 연산자가 있어야 인스턴스를 생성하면서 그 주소값을 반환하게 하는 연산자인 것 같다.
생성자는 인스턴스 변수 초기화이지 그 이상(인스턴스 생성)도 그 이하도 아닌 것 같다.

더 읽어보기 »

오늘은 기본값을 위해 많이 쓰던 논리 연산자인
||와 &&을 집중 탐구해보았다.
우선 위에 있는 녀석들은 어떨 때 쓰는지 알아보자.

사용 사례

  • 네임 스페이스 패턴(~ES5)
    웹팩을 사용하면 js 파일을 모듈 단위로 사용할 수 있지만,
    그럴 환경이 안 되면 아래와 같은 우회 방법을 통해서 전역 스코프를 최대한 덜 더럽힐 수 있다.
    ES6에는 모듈 import, export 기능이 있어서 ~ES5라고 써놓긴 했지만…
    아직 지원하는 브라우저가 없는 걸로 안다. (17년 2월 기준)
1
2
3
4
5
6
7
8
9
10
11
// 전역 스코프에는 namespace와 namespace2 모듈만이 존재한다.
// func라는 충돌나기 쉬운 네이밍이 전역에 존재하지 않으므로 충돌이 일어나지 않는다.
// 즉 네이밍을 고민할 염려가 조금은 줄어들게 된다. 뭐 그 외에 장점도 많지만...
// script src 태그를 통해 미리 namespace 모듈을 불러온 경우에는 전역에는 변수 namespace가 존재한다.
// || 연산자를 써서 전역에 namespace라는 변수(모듈)가 존재하면 그 모듈을 변수에 할당하고,
// 존재하지 않는다면 빈 객체를 변수에 할당하는 패턴이다.
const namespace = namespace || {};
namespace.func = function() {};

const namespace2 = namespace2 || {};
namespace2.func = function() {};
더 읽어보기 »

이 글은 Outsider 님의 블로그 포스트 중
forEach에 break문 대신 some 사용하기를 보고 큰 감명을 받아
내가 이해한 내용을 토대로 정리해 본 글이다.

for loop

for 반복문을 써서 배열을 순회하는 것은 할당, 프로퍼티 참조, 조건 분기 등등의 잡다한 일을 해야한다.
이러한 잡다한 일을 실수로 코딩을 잘못하면 원하지 않는 결과가 나오고, 귀찮음이 몰려오기 마련이다.

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
43
44
45
46
47
48
49
50
51
52
const arr = [
0, 1, 2, 3, 'q', 5, 6, 3.3, 5, 6, 3.3, 5, 6, 3.3,
5, 6, 3.3, 5, 6, 3.3, 5, 6, 3.3, 5, 6, 3.3
];

// 배열이 숫자로만 이루어져있는지 파악하는 함수
const isArrNum = arr => {
let isNum = true;

// 프로그래머가 실수로 let i = 1;이라고 초기화한다면?
// 실수로 i<arr.length+1; 이라고 조건식을 잘못 입력한다면?
// i+=2; 라고 증감식을 잘못 입력한다면?
// arr[i+1]로 잘못 참조한다면?
// 이렇게 일일이 초기화, 조건식 지정, 증감식 지정 등등을 일일이 해줘야하므로 귀찮다.
for(let i=0; i<arr.length; i++) {
console.log(arr[i]);
if(!isNaN(arr[i])) { // 숫자라면
// 아래 있는 코드는 실행할 필요 없이 다음 요소를 검사해야함.
// 즉 다음 반복문을 실행.
continue;
}
// 숫자가 아니라면
isNum = false;

// 바로 반복문을 종료해야함.
break;
}

return isNum;
};


// 0
// 1
// 2
// 3
// q
// false
console.log(isArrNum(arr));

// 사실은 아래와 같이 break와 continue를 쓸 필요도 없는 예제긴 하다.
const isArrNum2 = arr => {
for(let i=0; i<arr.length; i++) {
if(isNaN(arr[i])) { // 숫자가 아니라면
// 반복문 탈출이고 나발이고 return으로 바로 함수를 조기 종료 시키면서
// false를 반환하게 하면됨.
return false;
}
}
// 반복문이 무사히 끝났으면 모든 게 숫자였다고 판단하여 true를 반환.
return true;
};
더 읽어보기 »

자바를 공부하면서 느낀 것이다.

초반엔 내가 아는 내용이니 하루에 한 챕터씩 나가야지..

하지만 내가 아는 게 다가 아니었다.
다 안다고 생각했지만 그 속에는 모르는 내용들이 너무 많았다.
하루 한 챕터를 정리해가면서 연습문제까지 풀어가기에는 정말 힘들었다.
초반에는 재밌어서 그래도 거의 한 챕터씩 나갔다.
하지만 가면 갈 수록 그 양에 질리고, 시간은 더욱 오래 걸렸다.
공부를 하는 것도 매일 매일이 아니라 그냥 생각날 때, 시간 날 때만 했다.
오늘 공부를 하다보니 이제는 지쳐서 2시간이 되자 책장을 넘기면서

이 챕터는 도대체 언제 끝나나…
다음 챕터는 얼마나 될라나…

더 읽어보기 »

어제는 친구들이랑 노느라 공부를 조금 밖에 못 했다.
그만큼 오늘은 좀 빡시게 달려야겠다.

재귀함수(recursive function)

함수 내에서 자기 자신을 호출하는 것이다.
배열의 요소를 모두 더하는 메소드는 아래와 같이 작성이 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class test {
static int sumArr(int[] arr) {
int sum = 0;
for(int num : arr) {
sum += num;
}
return sum;
}
public static void main(String[] args) {
int arr[] = {1, 2, 4, 5 , 8, 9};
int sum = sumArr(arr);
System.out.println(sum);
}
}
더 읽어보기 »

JVM의 메모리 구조

이 글을 보기 전에 아래 글을 참조하면 더 이해가 잘 간다.
(C/C++) 참고용 정리 - 메모리 영역(Code, Data, Stack, Heap)

  • Method Area
    클래스 데이터가 들어간다.
    즉 클래스 변수(static 변수)가 들어간다.
    프로그램 실행되자마자 적재되고 끝날 때까지 사라지지 않는 놈이다.
    기본적인 메모리 영역의 Data 영역에 해당한다.
  • Call Stack
    메소드가 호출되면 해당 메소드를 콜스택에 push한다.
    제어권이 이전에 실행 중이던 메소드에서 Stack의 top에 위치한 메소드로 이동하게 된다.
    이전에 실행 중이던 메소드는 대기 상태가 되고 호출한 메소드의 작업이 끝날 때까지 대기하게 된다.
    그러면서 해당 메소드 만의 스코프를 생성한다.
    별도의 스코프를 생성하므로 지역 변수가 이곳에 존재한다.
    해당 메소드 아래 있는 메소드가 해당 메소드를 호출한 메소드가 된다.
    JVM은 프로그램이 실행되면 일단 main 메소드를 찾아 콜 스택에 push하게 된다.
    그리고 메소드의 작업에 필요한 메모리 공간을 콜스택이 제공해주고,
    작업을 마치게 되면 할당 되었던 메모리 공간은 반한된다.
    기본적인 메모리 영역의 Stack에 해당한다.
  • Heap
    클래스의 인스턴스가 생성되는 공간.
    인스턴스 변수들이 들어간다.
    new 연산자를 쓰므로 동적 할당이라고 할 수 있다.
    메모리 상에서 해제는 가비지 컬렉터가 자동으로 수행한다.
    기본적인 메모리 영역의 Heap에 해당한다.

학교에서 클래스를 할당하는 한 가지 방법 밖에 배우지 않았다.
동적 할당에 대해서 배우지 않았기 때문인데…
왜 학교에서는 이런 심도있는 내용들은 1도 가르쳐주지 않는 걸까?
학교에서 이런 내용까지 알려준다면 좀 더 재미나게 수업에 임할 수 있을텐데…
정말 안타깝다 ㅠㅠ
이해를 돕기 위해 아래 포스트를 한 번 보는 걸 추천한다.
(C/C++) 참고용 정리 - 메모리 영역(Code, Data, Stack, Heap)

학교에서 배운 방법(정적 할당)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;

class test {
private:
int num;
public:
void setNum(int n) {num = n;}
int getNum() {return num;}
};

int main() {
test t;
t.setNum(22);
cout << t.getNum() << endl;
cout << t; // 에러, t가 가지고 있는 순수 값은 못 본다. 왜일까? ㅠㅠ
return 0;
}

test 클래스의 인스턴스인 t는 스택 영역에 올라가게 된다.
사실 자바를 먼저 배우고 C++을 그 이후에 배워서…
자바에서는 저렇게 선언하면 참조변수만 선언한 격이라
클래스의 인스턴스가 생성되지 않아서 할 수 있는 게 1도 없었는데…
자바에서는 클래스의 정적 할당이 없어서 그랬나 보다.

더 읽어보기 »
0%