인사이드 자바스크립트를 공부하며 정리하는 포스팅입니다.



배열(Array)

배열은 자바스크립트 객체의 특별한 형태다. C의 배열과 유사하지만 크기를 지정하지 않아도 되며, 어떠한 타입의 데이터를 저장하더라도 상관없다.




1. 배열 생성

배열의 생성은 두 가지 방법으로 할 수 있습니다.

일반적으로 배열 리터럴 방식으로 생성합니다.


1) 배열 리터럴

[] 대괄호 문법을 이용한 리터럴 방식으로 배열 생성


var str = 'test';
var colorArr = ['orange', 'yellow', blue];

2) 생성자 함수를 이용한 생성

호출할 때 인자가 1개이고, 숫자인 경우: 호출된 인자를 length로 갖는 빈 배열을 생성한다.

그 외의 경우: 호출된 인자를 요소로 갖는 배열 생성.

var colorArr = new Array(3);
colorArr.push('orange');
colorArr.push('yellow');
colorArr.push('blue');
//var colorArr = new Array('orange', 'yellow', 'blue');


2. length 프로퍼티

배열의 원소 개수를 나타낸다. 그러나 배열에 존재하는 실제 원소 개수와 일치하는 것은 아니다. 

배열 내에 가장 큰 인덱스에 1을 더한 값이다.


배열의 가장 큰 인덱스값이 변하면, length 값 또한 자동으로 그에 맞춰 변경된다.

var arr = []; arr[0] = 1; arr[100] = 2; console.log(arr.length); // 101


배열의 length 프로퍼티는 명시적으로 값을 지정할 수도 있습니다.

만약 현재 배열의 length보다 큰 값을 지정한다면 현재 length Index 이후 값들은 undefined로 채워지게 됩니다.


length는 배열 표준 메서드에 영향을 미친다.


배열 표준 메서드인 push 메서드는 length값을 기준으로 수행됩니다. 

만약 length가 5라면 length는 마지막 Index + 1이므로 push 메서드의 수행결과로 새롭게 추가될 원소의 자리는 배열[length]가 되게됩니다.

length 프로퍼티는 이렇게 배열 표준 메서드에 영향을 미칠 수 있는 프로퍼티이므로 중요합니다.


이렇게 중요한 length 프로퍼티가 객체에 프로퍼티로 존재하면 어떻게될까요?

자바스크립트에서는 이렇게 length 프로퍼티를 가진 객체를 유사 배열 객체라고 부릅니다. 


* 배열에 동적으로 프로퍼티가 추가되어도 length는 증가하지 않는다. 배열의 length 프로퍼티는 오직 배열 원소의 가장 큰 인덱스가 변했을 경우만 변경된다.




3. 배열과 객체

자바스크립트에서는 배열 역시 객체입니다. 


객체와 배열의 typeof 값은 둘 다 Object로 동일합니다. 


그치만 분명히 배열과 객체는 다릅니다.

- length 프로퍼티의 존재 여부

- 배열 표준 메서드 존재 여부


이러한 차이점이 생기는 이유는 

객체의 경우 프로토타입으로 Object.prototype 객체를 갖고,

배열의 경우 프로토타입으로 Array.prototype 객체를 갖게되기 때문입니다.


length, 배열 표준 메서드는 Array.prototype 객체가 가지고 있는 프로퍼티입니다.


3. 배열의 프로퍼티 열거


배열을 객체와 같이 for in 문으로 프로퍼티를 열거하면 의도치 않은 동작이 수행될 수 있습니다.


var arr = ['a', 'b' , 'c']; arr['name'] = 'song'; for(var prop in arr) { console.log(prop, arr[prop]); } //0 a //1 b //2 c //name song //....여러가지 배열 프로퍼티 for(var i = 0; i< arr.length; i++){ console.log(i, arr[i]) } //0 "a" //1 "b" //2 "c"

위와 같이 for in문을 사용하면 배열의 원소 뿐아니라 여러가지 프로퍼티들도 같이 출력되게 됩니다. 의도치 않은 동작이 수행될 수 있겠죠?

때문에 배열의 원소를 탐색할 때에는 for문을 사용하는 것이 좋습니다.


4. 배열의 요소 삭제


1) delete

delete 연산자는 length 값은 그대로 유지한채 삭제합니다. 즉, 배열의 원소값을 undefined로 바꿔줍니다.


2) splice

만약 배열의 요소를 완전히 삭제하고 싶다면 splice()메서드를 이용해서 배열의 요소를 삭제할 수 있습니다.


splice(start, deleteCount, item...)

- start: 배열에서 시작 인덱스

- deleteCount: 삭제할 요소의 수

- item: 삭제할 위치에 추가할 요소

 




인사이드 자바스크립트를 공부하며 정리하는 포스팅입니다.



참조 타입(객체)


자바스크립트에서 기본 타입을 제외한 모든 값은 객체다.

따라서 배열, 함수, 정규표현식 등도 결국 자바스크립트 객체로 표현된다.

자바스크립트에서 객체는 단순 key : value 형태의 프로퍼티들을 저장하는 컨터이너로써, Hash와 유사하다. 
프로퍼티에는 기본 타입, 참조 타입(객체), 함수등 모든 타입을 포함할 수 있다.



1. 객체 프로퍼티 접근


객체 프로퍼티를 읽고, 쓰고, 갱신하기 위해 접근하는 방법은 두 가지가 있습니다.


- 대괄호([]) 표기법

- 마침표(.) 표기법


일반적으로는 C++, Java등의 언어와 유사하게 마침표 표기법을 많이 사용하지만 대괄호 표기법만을 사용해야하는 경우가 있습니다.

1) 프로퍼티 이름이 표현식인 경우 // foo['full-name'] = 'foo song';

2) 프로퍼티 이름이 예약어인 경우 




2. for in 문


for in 문을 사용하면, 객체에 포함된 모든 프로퍼티에 대해 루프를 수행할 수 있습니다.

var objA = {

val : 40

};



var objB = objA;



console.log(objA.val); // 40

console.log(objB.val); // 40



objB.val = 50;



console.log(objA.val); // 50

console.log(objB.val); // 50
for in 문을 수행하면서 변수에 객체의 프로퍼티가 하나씩 String 타입으로 할당됩니다.



3. 객체 프로퍼티 삭제


자바스크립트에서는 객체의 프로퍼티를 delete 연산자를 이용해 즉시 삭제할 수 있습니다.


delete foo.name;


4. 참조 타입의 특성


자바스크립트에서 객체는 참조 타입입니다. 

말그대로 객체의 모든 연산이 실제 값이 아닌 참조값으로 처리되기 때문입니다.

var objA = {

val : 40

};



var objB = objA;



console.log(objA.val); // 40

console.log(objB.val); // 40



objB.val = 50;



console.log(objA.val); // 50

console.log(objB.val); // 50

objB의 프로퍼티를 수정해도 objA의 프로퍼티가 같이 수정됩니다. 따라서 두 객체는 같은 객체를 가리키고 있다는 것을 알 수 있습니다.


var objA = {}; 


위와 같이 객체를 생성되면 objA 자체의 값이 객체인 것이 아니라 생성된 객체를 가리키는 참조값을 저장하고 있는 것입니다.

 

객체비교도 마찬가지 입니다.

var objA = {

val : 40

};



var objB = {

val : 40

};



var objC = objB;



console.log(objA == objB); // false

console.log(objB == objC); // true

변수는 객체의 값이 아닌 객체의 참조값을 가지고 있기 때문에 모든 값이 동일한 objA와 objB는 다른 객체이고, 참조값이 같은 objB와 objC는 같습니다.


* 다음 포스팅에 깊은복사와 객체간 값 비교를 통해 비교하는 함수를 만들어 보도록 하겠습니다. 



4. 참조에 의한 호출 방식 (call by reference)


기본 타입과 참조 타입의 경우는 함수 호출 방식도 다릅니다. 기본 타입의 경우는 call by value/ 참조 타입은 call by reference 입니다.


call by value: 함수를 호출할 때 인자로 복사된 값을 전달한다. 즉, 함수내에서 매개변수의 값을 변경해도 실제 값은 변경되지 않는다.

call by reference: 함수를 호출할 때 인자로 객체의 참조값이 전달된다. 즉, 함수내에서 매개변수의 값을 변경하면 실제 값이 변경된다.


위에서 4. 참조 타입의 특성으로 보면 알 수 있듯이 참조 타입은 값 자체가 아닌 가리키고 있는 참조값입니다. 때문에 함수 내에서 인자로 받은 객체의 프로퍼티를 수정하면 원본 객체의 프로퍼티가 수정됩니다.


c++을 하셨던 분들은 포인터를 생각하시면 이해가 빠를듯 합니다. 변수에 할당된 것은 값이 아니고 주소이고, 그 주소에 있는 값을 변경하는 것이라고 생각하시면 됩니다.



5. 프로토타입


자바스크립트의 모든 객체는 자신의 부모 역할을 하는 객체와 연결되어 있습니다. 마치 객체지향의 상속과 유사하게 부모 객체의 프로퍼티를 자신의 것처럼 사용할 수 있습니다. 자바스크립트에서는 이러한 부모 객체를 프로토타입이라고 부릅니다. 


ECMAScript 명세서에는 자바스크립트의 모든 객체는 자신의 프로토타입을 가르키는 [[Prototype]]이라는 숨겨진 프로퍼티를 가진다고 설명합니다. 이를 크롬 브라우저에서는 _proto_라 되어있습니다.



foo 객체의 프로토타입 객체는 Object.prototype 객체입니다. (객체의 최상위 프로토타입) 따라서 foo 객체는 Object.prototype에 정의된 프로퍼티들을 사용할 수 있습니다.


자바스크립트에서 굉장히 중요한 개념입니다. 이후에 따로 프로토타입, 프로토타입 체이닝, 상속에 관하여 심도있게 포스팅을 작성해볼 예정입니다^^.





인사이드 자바스크립트를 공부하며 정리하는 포스팅입니다.




자바스크립트 데이터 타입


언어의 기본인 데이터 타입입니다.

자바스크립트의 데이터 타입은 크게 아래와 같이 분류할 수 있습니다.




기본 타입



1. Number


자바스크립트에서는 단 하나의 숫자형만 존재합니다. 모든 숫자를 64비트 부동 소수점 형태로 저장합니다.


2. String


문자열은 작은 따음표('), 큰 따옴표(")로 생성할 수 있습니다.


자바스크립트에서는 C++의 문자열 배열과 같이 문자열에 접근은할 수 있지만 수정은 할 수 없습니다. 

자바스크립트에서는 한 번 생성된 문자열은 읽기만 가능하지 수정은 불가능합니다.


var str = 'test';
str[0] = 'T';
console.log(str); //결과는 'test'


3. Boolean


자바스크립트에서는 true와 false 값을 나타내는 Boolean 타입을 가진다.



4. null, undefined


이 두 타입은 모드 자바스크립트에서 '값이 비어있음'을 나타낸다. 

기본적으로 값이 할당되지 않은 상태의 변수는 undefined이다. 


undefined 타입 변수의 값 자체도 undefined 이다. 즉, undefined는 타입이자 값을 나타낸다.

null 타입 변수의 경우는 개발자가 명시적으로 값이 비어있음을 나타내는 데 사용한다.


null 타입 변수의 typeof의 결과는 object이다. 


때문에 함수내에서 예외처리시 if(typeof test === 'object')와 같은 형태로 사용하다가 null 타입 변수가 의도치 않게 통과될 수 있습니다. 주의하여야 합니다. 저도 종종 이러한 실수를 한 적이 있습니다.. 


null 타입 변수인지를 확인할 때에는 typeof 연산자가 아닌 값으로 확인해야 합니다.



Cascading?


: css 적용 우선순위

css는 한 가지의 속성값에 여러 가지의 값이 정의될 수 있습니다. 이 때 어떠한 값을 따라야 할 지 우선순위를 Cascading이라고 합니다.


기본적인 규칙은 더 구체적인 것/명시적인 것이 우선순위가 높습니다.


1. Style 속성

2. id 선택자

3. class 선택자

4. tag 선택자



'!important;'를 붙여서 절대적으로 우선순위를 높이는 방법도 있습니다.


좋은 방법은 아니므로 되도록 우선순위에 따라서 맞춰서 CSS를 작성하시는 편이 좋습니다.








Tech/Mac

[Mac] HomeBrew 설치

2018. 3. 17. 22:23

HomeBrew?


HomeBrew란 macOS용 패키지 관리자입니다.


홈페이지: https://brew.sh/index_ko



1. 설치


설치법은 매우 매우 간단합니다.

터미널에 아래와 같이 타이핑만 해주시면 됩니다. 


/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"


2. 사용법


1) install


brew install "package 이름"

  • cask 

cask는 HomeBrew의 확장 기능으로 설치와 동시에 설정을 해주는 편리한 기능입니다.


  • iterm2 설치
iterm2는 간단하게 터미널의 확장판이라고 보시면 됩니다.
아래와 같이 터미널에 입력하시면 iterm2가 설치됩니다.

 brew cask install iterm2



1. Git Repogitory 생성


처음에 해볼 것은 로컬 디렉터리를 Git Repogitory로 만드는 것입니다. 매우 간단합니다 ㅎㅎ


1) 터미널을 통해 git Repogitory로 사용할 로컬 디렉터리로 이동한다.

2) git init 을 입력한다.


이렇게 해주시면 아래와 같이  .git이라는 디렉터리가 생성된 것을 보실 수 있습니다.




2. 원격저장소에서 Repogitory 가져오기


이번에는 원격저장소에 있는 Repogitory를 로컬로 가져와보겠습니다.

github에 있는 원격저장소에는 주소가 있습니다. 그 주소를 통해서 원격저장소에 있는 Repogitory를 가져올 수 있습니다.



1) 원격 저장소에서 가져올 Repogitory를 저장할 디렉터리로 이동

2) git clone "주소"


제가 git clone https://github.com/iamsjy17/songta 라고 입력하였고 결과는 songta 라는 Repogitory를 로컬로 복사해서 가져왔습니다.





3. Git Config 설정


로컬 저장소를 생성하거나 원격저장소를 가져온 상태에서 이후 commit을 하기 위해서는 config를 설정 해줘야합니다.

git config --global user.name "사용자 이름"
git config --global user.email "사용자 이메일"


위와 같이 사용자 정보를 설정하면 이후에는 /.gitconig에 저장이 되고 초기에 한번만 설정해주시면 됩니다.


이제부터 git을 사용하여 버전관리를 하실 수 있습니다!!


어셈블리는 하나의 단일한 단위로 존재하는 .NET의 실행 가능한 프로그램 또는 실행 프로그램의 일부이며  실행 및 배포의 단위라고 할 수 있다. C# 응용 프로그램 작성의 결과로 생긴 .exe 파일, 클래스 라이브러리 작성의 결과인 DLL이 각각 하나의 어셈블리 이다.


하나의 단일한 어셈블리 안의 모든 코드는 하나의 단일한 단위로 빌드, 배포되며 버전 번호가 부여되는데 각 어셈블리는 다른 프로그램들이 사용 할 수 있는 pulic class, 속성, 메소드 등을 노출하고, private으로 선언된 것들은 모두 어셈블리 안에 은폐된다.


 

Tech/Win32 API

입력 1. 키보드

2016. 11. 16. 01:03

키보드 입력시에 메시지가 WM_KEYDOWN, WM_CHAR, WM_KEYUP 순으로 발생한다


1. WM_KEYDOWN

키보드 입력시 처음으로 발생하며, 문자 이외의 키(fn, Ins, 방향키등)를 처리할 때 주로 사용한다.  

wParam으로 문자 코드가 아닌 가상 코드(키보드의 종류의 상관없이 키를 입력받기 위해 만들어진 코드 값)가 들어온다. 


2. WM_CHAR

사용자에 의해서 발생하는 메시지가 아닌 TranslateMessage() 함수에 의해서 만들어진 메시지이다.

TranslateMessage() 함수는 전달된 메시지가 WM_KEYDOWN인지와 문자 키인지 검사하여 조건을 충족하면 WM_CHAR 메시지를 만들어서 메시지 큐에 넣어준다.


- lParam : Alt와 같은 특수 키

- wParam : 문자 아스키 코드값


3. WM_KEYUP

키를 땔 때 발생하는 메시지이다.

'Tech > Win32 API' 카테고리의 다른 글

무효 영역(Invalid Region)  (0) 2016.11.15
DC(Device Context)  (0) 2016.11.13

WM_PAINT 메시지는 윈도우가 다시 그려져야 할 때마다 호출되게 됩니다. 즉 무효 영역이 있는 경우 호출되게 됩니다. 

다시 말하면 윈도우 프로시저는 클라이언트 영역의 일부가 무효화될 때만 WM_PAINT 메시지를 받습니다.

무효영역이 생기는 경우는 두 가지 입니다.


1. 윈도우 일부가 지워젔을 때(예를 들면 윈도우에 가려졌던 부분이 드러날 때)


2. InvaildateRect함수가 호출 될 때


BOOL InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase);  


첫 번째 인자는 다시 그려져야할 윈도우의 핸들입니다.


두 번째 인자는 무효화의 대상이 되는 직사각형 영역입니다. 만약 두 번째 인자에 NULL을 넣는다면 클라이언트 영역 전체가 무효화되게 됩니다. NULL을 넣으면 전체를 다시 그리므로 확실히 그려지겠지만 느립니다. 따라서 속도를 높이려면 변경된 최소한의 영역만을 계산하여 무효화 하는 것이 좋습니다.


세 번째 인자는 무효화되기 전에 배경을 모두 지운 후 다시 그릴 것인지 아니면 배경을 지우지 않고 그릴 것인지를 정합니다. TRUE이면 배경을 지우고, FALSE이면 배경을 지우지 않습니다.



윈도우즈는 내부적으로 각 윈도우에 대해 '그리기 정보 구조체(paint information structure)'를 유지합니다. 이 구조체 안에 여러 정보 중에는 무효 영역을 감싸는 최소 크기의 직사각형 좌표(invalid rectangle)이 들어 있습니다. 

* 그리기 정보 구조체 == PAINTSTRUCT

* invalid rectangle == rcPaint


이 무효 직사각형이 우리가 그려야 할 영역입니다. 


만약 대기 중인 WM_PAINT 메시지를 우도우 프로시저가 처리하기 전에 또 다른 부분이 무효화된다면, 윈도우즈는 두 개의 무효 영역을 포함하는 새로운 무효 영역을 그리기 정보 구조체에 갱신합니다. 즉, 윈도우즈는 메시지 큐에 두 개 이상의 WM_PAINT 메시지를 넣지 않습니다.


클라이언트 영역의 무효 영역 전체가 유효화된다면, 메시지 큐에 현재 저장되어 있는 WM_PAINT는 제거됩니다.




'Tech > Win32 API' 카테고리의 다른 글

입력 1. 키보드  (0) 2016.11.16
DC(Device Context)  (0) 2016.11.13

Tech/Win32 API

DC(Device Context)

2016. 11. 13. 01:34

DC(Device Context)란?

출력에 필요한 모든 정보를 가지는 데이터 구조체이며, GDI(Graphic Device Interface)모듈에 의해 관리됩니다.

화면으로 출력 하기 위해서는 반드시 DC가 있어야 합니다.


이 DC를 얻는 방법은 두 가지가 있습니다.


우리는 인수로 전달 된 창(Window)의 핸들(HWND)로 부터 GetDC, BeginPaint 함수를 통해 DC를 가져올 수 있습니다.

이 때 중요한 것은 DC를 무사히 다 사용했으면 반드시 ReleaseDC, EndPaint함수를 통해 반환해야 합니다. DC도 메모리를 차지하므로 반드시 할당 후 해제 원칙이 준수되어야 합니다.


두 가지 방법에 대해 하나씩 보겠습니다.


1. GetDC 함수를 통해 얻어오는 방법


WM_PAINT 이외의 메시지에서 클라이언트 영역 일부를 그리고자 할 때 또는 그 밖의 목적으로 디바이스 컨텍스트 정보를 필요로 하는 경우 사용하는 함수입니다.


HDC GetDC(HWND hWnd);

int ReleaseDC(HWND hWnd, HDC hDC);


GetDC가 리턴하는 DC 핸들의 클리핑 직사각형 영역은 전체 클라이언트 영역입니다.

그리고, BeginPaint와 달리 GetDC는 무효 영역을 유효화하지 않습니다. 클라이언트 영역 전체를 유효화해야 한다면 다음과 같은 함수를 호출해야 합니다.

 

ValidateRect (hWnd, NULL);



2. WM_PAINT 메시지 루틴내에서 DC를 얻어오는 방법


WM_PAINT 메시지 루틴에서는 DC를 GetDC로 얻지 않고 BeginPaint함수로 얻고, EndPaint함수로 해제해 주어야 합니다.


HDC BeginPaint(HWND hWnd, LPPAINTSTRUCT lpPaint);

BOOL EndPaint(HWND hWnd, CONTST PAINTSTRUCT *lpPaint);


BeginPaint함수가 호출되면 클라이언트 영역은 모두 유효화 되게 됩니다.

BeginPaint함수는 윈도우 핸들 외에도 페인트 정보 구조체를 인수로 필요로 합니다. 이 구조체는 그림 그리기에 필요한 정보를 담습니다.


typedef struct tagPAINTSTRUCT {


HDC    hdc;

BOOL   fErase;

RECT    rcPaint;

BOOL   fRestore;

BOOL   fIncUpdate;

BYTE    rgbReserved[16];

} PAINTSTRUCT;


앞의 세 멤버는 사용자가 사용하는 멤버이며 나머지 세 멤버는 윈도우즈가 내부적으로 사용하므로 사용자가 건드려서는 안됩니다.



'Tech > Win32 API' 카테고리의 다른 글

입력 1. 키보드  (0) 2016.11.16
무효 영역(Invalid Region)  (0) 2016.11.15