레이블이 자바스크립트인 게시물을 표시합니다. 모든 게시물 표시
레이블이 자바스크립트인 게시물을 표시합니다. 모든 게시물 표시

2015년 8월 14일 금요일

자바스크립트 오브젝트 모델 및 상속구조


자바스크립트의 오브젝트 모델 및 상속구조에 대해서 자세하게 살펴본다. 학습테스트는 자바스크립트 테스트 프레임워크인 자스민을 이용해서 작성되었다. 자스민에 대한 사용법은 이 전에 작성했던 "자스민 사용법" 글을 참조하자.

클래스 기반의 객체모델과  프로토타입 기반의 객체 모델

자바와 같은 클래스 기반의 객체 모델을 사용하는 언어에서는 두 가지 분명하게 구분되는 개념이 있다. 바로 클래스와 인스턴스이다. 클래스는 특정 집합에 속하는 객체들의 특성들을 멤버변수와 메서드로 추상화한다.예를 들어, Talent 클래스는 "재능이 있는 사람들" 의 일반적인 특성을 추상화 한다. 반면에 인스턴스는 특정 재능이 있는 사람 한 명을 나타낸다. 예를 들어 SteaveJobs는 Talente  클래스가 실체화된 인스턴스로 Talent 클래스의 모든 속성들을 가지고 있다.   

자바스크립트와 같은  프로토타입 기반의 객체 모델을 사용하는 언어에서는 클래스와 인스턴스의 명확한 구분이 없고, 단순히 오브젝트이다. 이러한 언어에서는 프로토타입이 되는 오브젝트가 존재한다. 그리고 프로토타입 오브젝트는 다른 오브젝트의 템플릿이 된다. 오브젝트가 생성이 될 때이던지, 실행시간이던지 어떤 오브젝트도 다른 오브젝트의 프로토타입이 될 수 있다. 프로토타입을 통해서 생성된 오브젝트는 프로토타입의 속성들을 공유한다.

자바스크립트에서 오브젝트를 만들 때, 자바에서과 같이 별도의 클래스를 정의할 필요없다. 대신 생성자 함수을 통해서 특정 속성들을 가지는 오브젝트를 정의할 수 있다. 어떤 자바스크립트 함수도 생성자 함수가 될 수 있으며,"new" 키워드와 생성자 함수를 이용해서 새로운 오브젝트를 생성할 수 있다.

Class-based
Prototype-based
클래스와 인스턴스가 구분된다.
모든 오브젝트는 다른 오브젝트로부터 상속될 수 있다.
명시적인 클래스의 정의가 필요하다. 클래스의 인스턴스화는 생성자를 통해서 가능하다.
생성자 함수를 통해서 오브젝트의 정의 및 생성이 가능하다.
new 연산자를 통해서 한 개의 객체를 생성한다.
동일하다.
클래스 정의를 통해서 서브클래스 및 클래스 상속구조를 정의한다.
생성자 함수와 함께 prototype 오브젝트를 할당함으로 상속구조를 정의한다.
실행시간에 동적으로 속성을 추가하는 것이 불가능하다.
생성자 함수나 prototype 은 단순히 최초 속성들의 집합만을 정의한다. 동적으로 속성을 추가하거나 제거하는 것이 가능하다.

이 포스트에서는 아래와 같은 상속구조를 가지는 예제를 이용할 것이다. 클래스 다이어그램에서 관해서는 UML 클래스 다이어그램 을 참조하자.



1. 상속구조
먼저 Talent 오브젝트와 이 오브젝트를 상속한 Painter 오브젝트를 살펴보자. [라인 10]을 살펴보면 Painter 오브젝트에서 Talent.call(this)  메서드를 호출하고 있다. call 함수에 대해서는 여기를 살펴보자. call 함수에 "this"  인자와 필요에 따라 추가적인 인자를 넘김으로서 상속받고자 하는 오브젝트의 생성자 함수를(여기서는 Talent ) 호출할 수 있다. 그리고 나서 [라인 13]에서 Painter.prototype 속성에 Talent.prototype 를 생성해서 할당해 주고 있다. prototype 은 자바스크립트에서 사용하는 특별한 속성으로서 모든 함수는 이 속성을 가지고 있다. 참고로 함수는 일반적으로 function funcName() {...} 으로 선언된 것을 의미하고, 메서드는 특정 오브젝트 멤버로서 존재하는 것을 의미한다.

자바스크립트의 내부적인 객체 생성과정을 살펴보자.

var psy = new Singer;

자바스크립트는 new 오브젝트가 있는 경우,  generic object을 생성해서 Singer 오브젝트의 생성자 함수의 this  키워드의 value 로 넘겨준다. 그리고 나서 생성자 함수에서 명시적으로 "majorTalent”속성을 할당한다. 그 다음으로 묵시적으로 내부적인 __proto__ 속성을 Singer 생성자 함수의 prototype 으로 할당한다. (__proto__ 속성은 특정 속성을 리턴할 때, 특정 속성의 값을 리턴하는  prototype 을 결정한다.)

자바스크립트에서 특정 속성을 읽을 때, 자바스크립트는 먼저 해당 속성이 오브젝트에 존재하는지 확인한다. 만약 있으면 해당 값을 리턴한다. 만약 없다면, 자바스크립트는 __proto__  속성을 이용해서  프로토타입 체인을 확인한다. 프로토타입 체인에 있는 오브젝트가 해당 속성의 값을 가지고 있으면, 그 값을 리턴한다. 만약 오브젝트가 프로토타입 체인에 존재하지 않으면, 자바스크립트는 해당 속성이 존재하지 않는다고 말한다.


2. 좀 더 유연한 객체 생성방법 - 생성자 함수에 매개변수 전달
생성자 함수가 인자를 받을 수 있게 하여 사용한다.


3. 좀 더 유연한 객체 생성방법 - 기본값 설정
[라인 4 ~ 6]에서와 같이 "||" 연산자를 이용해서 속성에 기본값을 설정할 수 있다. 값이 있는 경우에는 인자로 넘어온 값을 그렇지 않은 경우에는  empty 값을 설정한다. [라인 11]에서는 base 속성에 Talent 오브젝트의 생성자 함수를 설정하고 있다. 사실 base 속성은 특별한 속성이 아니다. 어떤 이름도 가능하다. 그리고 나서 [라인 12] 에서 생성자 함수를 호출하고 있다.

4. 왜 "prototype" 속성을 명시적으로 할당하는 것을 선언해주어야 하는가?
TalentedForMusic 과 TalentedForPaint 생성자 함수를 잘 살펴보자. TalentedForMusic 은 부모 생성자 함수의 prototype 속성을 할당해 주지 않았다. [라인 43 - 46] 을 살펴보자. [라인 43]에서처럼 Talent.prototype 에 추가적인 속성을 정의하는 경우, 부모 생성자 함수의 prototype 속성을 할당하지 않았던 TalentedForMusic 의 인스턴스인 hummingMan 오브젝트에는 이 속성이 추가되지 않는다.

5. "객체 생성자 함수에서 속성" vs "object.prorotype.property = value"
Talent의 "name" 속성과 "grade" 속성을 유심히 살펴보자. "name" 속성은 생성자 함수 내부에서 선언을 했고, "grade" 속성은 Talent.prototype.grade = "none" 과 같이 prototype 의 속성으로 선언을 했다. 이것은 주요한 차이가 있다. [라인 32 - 43] 에서와 같이 name 속성에 새로운 값을 할당하더라도, 그 인스턴스의 값은 변하지 않는다. 하지만, prototype 의 속성으로 선언되는 경우 [라인 46 - 48] 에서 볼수 있듯이, 새로운 값을 할당하는 경우 그 오브젝트의 인스턴스들의 값들이 모두 변하는 것을 알 수 있다.

6. instanceof, __proto__
[라인 38] 에서과 같이 instanceof 을 통해서 어떤 오브젝트의 인스턴스인지 알 수 있다.
자바스크립의 Object을 제외한 모든 오브젝트는 __proto__ 라는 특별한 속성을 가지고 있다. (자바스크립의 모든 함수는 prototype 이라는 특별한 속성을 가지고 있다.) 이 속성은 오브젝트가 생성될 때 생성자 함수의 prototype 이 할당된다. [라인 39 - 41]에서 볼 수 있듯이 오브젝트의 __proto__ 속성과 생성자 함수의 prototype 속성이 동일함을 알 수 있다.

7. 오브젝트 생성자 함수에서의  글로벌 변수 사용
오브젝트의 생성자 함수에서 글로벌 변수를 사용을 할 때는 주의를 하여야 한다. [라인 35]에서 count가 1일 것을 기대했을 수도 있지만 사실 결과는 3이다. [라인 32], [라인 29], [라인 17]에서 호출되기 때문이다. 즉, prototype 을 할당할 때도 호출된다. 


8. 자바스크립트는 다중 상속을 지원하지 않는다.
TalentForMusic 생성자 함수에서 Talent 와 Personality 두 오브젝트를 생성하는 것처럼 보인다. 실제로  Personality 의 속성을 TalentForMusic 에서 사용할 수 있다. 하지만, [라인 35]에서 보는 것처럼 Personality에 새로운 속성을 추가하는 경우, TalentForMusic 에는 추가되지 않는 것을 알 수 있다.


9. 참조
- MDN - https://developer.mozilla.org/en/docs/Web/JavaScript
- Jasmine - http://jasmine.github.io/2.3/introduction.html

2015년 8월 9일 일요일

자바스크립트 오브젝트

자바스크립트의 오브젝트에 대해서 살펴본다. 학습테스트는 자바스크립트 테스트 프레임워크인 자스민을 이용해서 작성되었다. 자스민에 대한 사용법은 이 전에 작성했던 "자스민 사용법" 글을 참조하자.

1. 오브젝트와 프로퍼티( object and property)
자바스크립트 단순한 형태를 가지는 오브젝트를 기반으로 설계되었다. 오브젝트는 속성들의 집합이다. 그리고 이 속성들은 이름과 값을 가지고,  오브젝트가 가지고 있는 여러 특성이나 동작을 표현한다.  자바스크립트에서는 변수에 값 뿐만 아니라, 함수(function)가 저장될 수 있기에, 여느 객체지향언어에서처럼 메서드(method)을 통해 객체의 동작을 표현할 수 있다. 객체와 속성은 아래와 같이 표현될 수 있다. 

objectName.propertyName

propertyName은 자바스크립트의 string 이거나, string으로 변환될 수 있는 것이어야 한다.


2.  속성 나열하기

객체의 속성은 fon-in 구문을 이용하거나, Object.keys(o), Object.getOwnPropertyNames(o) 을 통해서 가능하다.

3. 오브젝트 생성하기

오브젝트는 initializer 을 이용하거나, construct function  또는 Object.create 을 통해서 가능하다.

4. 프로토타입 속성
모든 자바스크립트의 오브젝트는 적어도 "prototype”이라는  오브젝트를 상속받는다. 그래서 [라인 14]에서 처럼 속성을 추가하였을 때, 모든 Male 인스턴스에 적용된다.

5. getter, setter 정의하기

6. 속성 삭제
7. 오브젝트 비교
8. 참조
- MDN - https://developer.mozilla.org/en/docs/Web/JavaScript
- Jasmine - http://jasmine.github.io/2.3/introduction.html

2015년 8월 8일 토요일

자바스크립트 map, set

자바스크립트의 Map과 Set의 자료구조에 대해서 살펴본다. 학습테스트는 자바스크립트 테스트 프레임워크인 자스민을 이용해서 작성되었다. 자스민에 대한 사용법은 이 전에 작성했던 "자스민 사용법" 글을 참조하자.

1. map basic
for-of  문을 이용해 map의 자료구조를 순회할 수 있다. [라인 11]에서 볼 수 있듯이, 이때 각각의 요소들은 [key, value]의 형태로 접근할 수 있다. key에 대한 동등성은 타입과 값을 모두 고려한 identity 연산자인 "===" 을 이용해서 평가된다.

2. object vs map
오브젝트와 맵을 비교해보자. 오브젝트의 key(속성) 은 string 으로만 정의되어야 하는 반면에, map 은 어떤 type 도 가능하다. map은 size 을 통해서 크기를 바로 알 수 있으나, 오브젝트는 메뉴얼로 순회하면서 크기를 계산하여야 한다.

3. set basic
[라인 16] 에서 알 수 있듯이, map의 key 의  동등성과 마찬가지로 타입과 값을 모두 고려한 identity 연산자인 "===" 을 이용해서 평가된다.

4. array and set
[라인 5] 에서 볼 수 있듯이, 배열에서 set 으로 변환시 중복된 값은 사라지고 오직 하나만 남게 된다.

5. 참조
- MDN - https://developer.mozilla.org/en/docs/Web/JavaScript
- Jasmine - http://jasmine.github.io/2.3/introduction.html

2015년 8월 4일 화요일

자바스크립트 배열

자바스크립트의 배열에 대해서 살펴본다. 배열과 관련된 다양한 함수들이 많다. 학습테스트는 자바스크립트 테스트 프레임워크인 자스민을 이용해서 작성되었다. 자스민에 대한 사용법은 이 전에 작성했던 "자스민 사용법" 글을 참조하자.

1. 배열의 선언 및 접근, 속성
[라인 2] 와 같이 명시적으로 Array 오브젝트를 생성할 수도 있고, [라인 8] 같이 단순하게 선언하고 사용할 수도 있다. [라인 20] 과 같이 배열의 요소에 자바스크립트의 어떤 타입이라도 사용이 가능하다. [라인 14, 15] 에서처럼 index 로 int 형이 아닌 다른 타입을 주게 되면, 오브젝트의 속성으로 생성이 된다.

2. length
[라인 5]에서 알 수 있듯이 자바스크립트의 length 는 단순히 가장 마지막 index + 1 이다.

3. iteration
for, for-each을 통해서 배열의 요소들을 순회할 수 있다. 물론 for-in 구문도 사용이 가능하다.

4. concat, push, pop, join
5. shift, unshift
6. slice, splice
splice 라는 함수는 배열의 특정 구간의 요소들을 지우고, 거기에 새로운 요소들을 삽입하는 함수이다. 배열 [1,2,3,4,5] 에서 2,3 요소가 삭제되고 거기에 "a","b","c" 가 삽입되어 [1,"a","b","c",4,5] 가 됨을 알 수 있다.

7. reverse, sort
8. indexOf, lastIndexOf
lastIndexOf는 배열의 마지막에서부터 검사를 한다.
9. forEach, map
배열의 각각의 요소를 인자로 받아 특정 작업을 하고자 할 때 유용하다.
10. every, some, reduce
배열 전체나 일부구간에 대한 검사등과 같은 작업을 할 때 유용하다.
11. Array Generic Method
12. 참조
- MDN - https://developer.mozilla.org/en/docs/Web/JavaScript
- Jasmine - http://jasmine.github.io/2.3/introduction.html


2015년 8월 1일 토요일

자바스크립트 표현식과 연산자

자바스크립트의 표현식과 연산자에 대해서 살펴본다. 기본적인 내용은 MDN 의 문서의 Expressions and Operators 를 참고하면 쉽게 알 수 있다. 자바스크립트에서만의 특이할만한 내용을 위주로 살펴본다. 학습테스트는 자바스크립트 테스트 프레임워크인 자스민을 이용해서 작성되었다. 자스민에 대한 사용법은 이 전에 작성했던 "자스민 사용법" 글을 참조하자.

1. equal, strict equal
자바스크립트는 동적타입 언어이므로 [라인 5]처럼 타입이 다를 경우 자동적으로 형변환을 시도한다. 만약 타입까지 일치하는지 확인하고 싶다면, [라인 7]처럼 strict equal 연산자인 "===" 을 사용하면 된다.
2. negation, plus
plus(+) 연산자는 number  형식으로 형변환을 시킨다.
3. string operator
4. delete operator
delete 연산자는 특정 오브젝트의 속성이나 배열의 특정 index 을 삭제할 수 있다. 삭제된 element는 [라인 9, 라인 15]처럼 undefined 가 된다.
5. typeof
typeof 연산자를 이용해서 type을 알 수 있다.
6. void(expression)
void 연산자는 [라인 5]에서처럼 expression을 평가한다. 하지만 [라인 6]에서처럼 아무것도 return 하지 않는다.
7. in operator
in 연산자는 특정 element 가 object 나 배열에 포함되어 있는지 확인한다.

8. 참조
- MDN - https://developer.mozilla.org/en/docs/Web/JavaScript
- Jasmine - http://jasmine.github.io/2.3/introduction.html


자바스크립트 반복문

자바스크립트의 반복문에 대해서 알아본다. 대부분은 일반적인 프로그래밍 언어와 비슷한  for, do-while, while 구문을 가지고 있다. 아래의 반본문들은 한번 살펴볼만 하다. 학습테스트는 자바스크립트 테스트 프레임워크인 자스민을 이용해서 작성되었다. 자스민에 대한 사용법은 이 전에 작성했던 "자스민 사용법" 글을 참조하자.

1. label with continue, break
[라인 3] 에서는 "firstLoop" 라는 label을 지정하였다. 이것은 중첩 반복문에서  특정 반복문을 빠져나올때 쓰면 유용하다. [라인 9]의  "break" 는  첫번째 반복문(for)을 빠져나오고, [라인 13]은 두번째 반복문(while)을 빠져나온다. 이는 "continue" 구문에서도 마찬가지이다.

2. for - in 구문
for - in  구문에서 object  의 경우는 속성이름이 사용되고, 배열에서는 index 가 사용된다.
[라인 8]에서는 p 가 object 에 들어있는 속성이름이 저장되고, 그 속성의 값에 접근할때는 [라인 9]에서처럼 접근할 수 있다. [라인 22]에서는 배열에서의 사용법을 보여준다.

3. for - of 구문
for - of  구문에서 index을 가져오지 않고, [라인 6] 바로 값에 접근한다.

4. 참조
- MDN - https://developer.mozilla.org/en/docs/Web/JavaScript
- Jasmine - http://jasmine.github.io/2.3/introduction.html

2015년 7월 28일 화요일

자바스크립트 Block Scope, Falsy Value, Error Handling

자바스크립트에서의 block scope ({ ... }) 와 False 로 취급되는 값들 그리고 throw 및 Error Handling에 사용할 수 있는 구문들을 알아본다. 학습테스트는 자바스크립트 테스트 프레임워크인 자스민을 이용해서 작성되었다. 자스민에 대한 사용법은 이 전에 작성했던 "자스민 사용법" 글을 참조하자.

1. 자바스크립트는 ECMAScript6 이전에는 Block Scope 을 가지고 있지 않다.


2. Falsy value
false, undefined, 0, empty string(""), NaN 은 false로 취급된다.

3. Throw expression, try - catch - finally
자바스크립트는 "throw" 라는 키워드를 통해 어떠한 "expression" 을 던질 수 있다. 이때 throw 된 녀셕들은 아래 예제의 [라인 15]와 [라인 43]에서처럼 catch 구문에서 받아서 사용이 가능하다. [라인 47]에서는 try - catch - finally 구문의 사용법을 보여준다.

4. Error Object
간단하게 Error Object을 던질 수 있다.
5. 참조
- MDN - https://developer.mozilla.org/en/docs/Web/JavaScript
- Jasmine - http://jasmine.github.io/2.3/introduction.html

2015년 7월 26일 일요일

자바스크립트 함수의 정의 및 사용

자바스크립트에서의 함수의 정의와 사용법에 대해서 살펴본다. 프로그래밍에 대해서 어느 정도 경험이 있다고 가정한다. 학습테스트는 자바스크립트 테스트 프레임워크인 자스민을 이용해서 작성되었다. 자스민에 대한 사용법은 이 전에 작성했던 "자스민 사용법" 글을 참조하자.

1. 함수의 정의와 사용
함수의 정의는 별다를게 없다. 라인 8을 유심히 보자. 라인 8에서 변수에 함수를 저장하고 있다. 이 말은 함수를 변수처럼 자유롭게 넘겨줄 수 있다는 말이다. 그리고 라인 11에서처럼 호출하는 것도 가능하다. 이 경우에는 변수 이름이 함수의 이름이 된다고 생각하면 된다.

2. call by value, call by reference
primitive type은 값(value)으로서 매개변수가 함수로 넘어간다. 배열이나 오브젝트와 같은 non-primitive type은 참조(reference)로서 매개변수가 넘어간다.

3. arguments
자바스크립트에서는 함수 오버로딩이 지원되지 않는다. 라인 6을 보면 그 이유를 알 수 있다. 함수에서 정의된 매개변수보다 많은 매겨변수를 사용하여 실제 그 함수가 호출된다면, 나머지 매개변수는 사용되지 않는다. 함수를 호출할때 어떤 값들을 매개변수로 넘겨줬는지 알고 싶을때가 있다. 이때는 "arguments" 라는 오브젝트를 참고하면 된다.  아래 예제에서의 func2 을 참고하자.

4. closure
자바스크립트에서는 closure 라는 개념을 지원한다. outside 라는 함수안에서 inside라는 함수를 정의하고, inside라는 함수 자체를 리턴한다. inside 함수에서는 outside 매개변수인 a 을 참조할 수 있다. 라인 9 와 라인 10과 같이 호출하는 것이 가능하다.

5. 참조 
- MDN - https://developer.mozilla.org/en/docs/Web/JavaScript
- Jasmine - http://jasmine.github.io/2.3/introduction.html

자바스크립트의 타입과 문법


자바스크립트의 기본적인 타입과 문법에 대해서 간단하게 살펴본다. 이 글을 읽는 독자는 기본적으로 프로그래밍 언어에 대한 경험이 있다고 가정하고 모든 내용을 자세하게 설명하지는 않는다. 자바스크립트만의 특이할만한 사항을 위주로 살펴본다. 학습테스트는 자바스크립트 테스트 프레임워크인 자스민을 이용해서 작성되었다. 자스민에 대한 사용법은 이 전에 작성했던 "자스민 사용법" 글을 참조하자.
  1. 자바스크립트는 동적 타입언어입니다.
    변수를 선언할 때 별다른 타입을 명시할 필요가 없고, 타입은 실행시간에 자동으로 변환이 됩니다. 아래의 예제에서는 변수를 선언할 때는 "var" 라는 키워드을 사용하였을 뿐, 특별한 타입을 명시하지 않았습니다. 또한 별다른 타입변환 없이 연산이 가능합니다.(물론 사용할때는 주의를 기울여야 합니다.)
  2. 변수
    "var" 키워드를 사용하지 않으면, global 변수를 의미합니다. 아래 예제에서 9 라인과 13 라인을 유심히 살펴보시기 바랍니다.
  3. undefined, null
    변수를 선언하고 아무값도 할당하지 않는 경우 "undefined" 으로 취급됩니다. 하지만 문맥에 따라 undefined 과 null 이 동적으로 변환이 이루어짐을 알 수 있습니다. "undefined" 은 숫자연산구문에서 NaN(Not a Number)으로 취급됩니다. 하지만 "null" 의 경우는 0으로 취급됩니다.
  4. constant
    constant 로 선언된 이름은 변수나 함수이름으로 다시 선언될 수 없습니다. MDN 문서에서는 constant 로 선언된 경우 값을 재할당하는 것도 안 된다고 했으나 테스트 해보니 잘 되었습니다. :-P
  5. array
    일반적인 프로그래밍 언어의 array 와 유사합니다. 라인 6와 같이 값이 없는 경우 undefined 로 취급됩니다. 
  6. object
    오브젝트의 선언과 오브젝트의 멤버들에 접근하는 방법을 유심히 살펴봐야 합니다. 라인 9 에서와 같이 멤버 이름(Key)을 숫자로 사용한 경우 배열과 같이 접근할 수 도 있습니다. 하지만 이름이 숫자가 아닌경우, 라인 4에서 사용한 방식이나 라인 6에서와 같은 방식으로 접근해야 합니다. 라인 8과 같은 경우는 사용할 수 없습니다. 자바스크립트 에러를 발생시키게 됩니다.
  7. 참고
    - MDN - https://developer.mozilla.org/en/docs/Web/JavaScript
    - Jasmine - http://jasmine.github.io/2.3/introduction.html