'WebFont-end/JavaScript'에 해당되는 글 27건

  1. [JavaScript] 전역객체 window
  2. [JavaScript] Object Model
  3. [JavaScript] arguments(유사 배열 객체)
  4. [JavaScript] 클로저 1
  5. [JavaScript] 유효범위
  6. [JavaScript] Object
  7. [JavaScript] prototype
  8. [JavaScript] 상속
  9. [JavaScript] this
  10. [JavaScript] 생성자와 new

[JavaScript] 전역객체 window


전역객체 window


1. Window 객체

Window 객체는 모든 객체가 소속된 객체(DOM, BOM, JavaScriptCore)이고, 전역객체이면서, 창이나 프레임을 의미한다. `

window.Array(JavaScriptCore)

window.navigator(BOM)

window.document(DOM)


2, 전역객체

Window 객체는 식별자 window를 통해서 얻을 수 있다. 또한 생략 가능하다. Window 객체의 메소드인 alert을 호출하는 방법은 아래와 같다.

<!DOCTYPE html>

<html>

<script>

    alert('Hello world');// window라는 객체내의 메서드

    window.alert('Hello world');

</script>

<body>

 

</body>

</html>


아래는 전역변수 a에 접근하는 방법이다.  

<!DOCTYPE html>

<html>

<script>

    var a = 1;

    alert(a);

    alert(window.a);//undefined

</script>

<body>

 

</body>

</html>


객체를 만든다는 것은 결국 window 객체의 프로퍼티를 만드는 것과 같다.

<!DOCTYPE html>

<html>

<script>

    var a = {id:1};

    alert(a.id);

    alert(window.a.id);

</script>

<body>

 

</body>

</html>

예제를 통해서 알 수 있는 것은 전역변수와 함수가 사실은 window 객체의 프로퍼티와 메소드라는 것이다. 또한 모든 객체는 사실 window의 자식이라는 것도 알 수 있다. 

이러한 특성을 ECMAScript에서는 Global 객체라고 부른다. ECMAScript의 Global 객체는 호스트 환경에 따라서 이름이 다르고 하는 역할이 조금씩 다르다. 

웹브라우저 자바스크립트에서 Window 객체는 ECMAScript의 전역객체이면서 동시에 웹브라우저의 창이나 프레임을 제어하는 역할을 한다.


'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] HTMLElement 객체  (0) 2014.12.22
[JavsScript] 제어 대상을 찾기  (0) 2014.12.21
[JavaScript] Object Model  (0) 2014.12.21
[JavaScript] arguments(유사 배열 객체)  (0) 2014.12.21
[JavaScript] 클로저  (1) 2014.12.21

[JavaScript] Object Model


Object Model


자바스크립트를 통해서 브라우저를 제어하기 위해서는 자바스크립로 제어할 무엇인가가 준비되어야 한다. 그것이 바로 Object(객체)이다.

웹브라우저의 구성요소들은 하나 하나가 객체화되어 있다. 자바스크립트로 이 객체를 제어해서 웹브라우저를 제어할 수 있게 된다. 

이 객체들은 서로 계층적인 관계로 구조화되어 있다. BOM과 DOM은 이 구조를 구성하고 있는 가장 큰 틀의 분류라고 할 수 있다.

자바스크립트로 브라우저를 제어하기 위해서는 객체를 제어한다.--> 객체화(자바스크립트로 브라우저를 제어하기 위해서는 모든 것이 객체화 되어 있어야 한다.)

브라우저 또는 웹페이지를 제어하기 위해서는 객체가 필요하고 그 객체를 만드는 주체는 웹브라우저가 준비하고 개발자는 준비된 그 객체를 자바스크립트를 통해서 웹브라우저 또는 문서를 제어할 수 있다.

이 관계를 그림으로 나타내면 아래와 같다. 



1. window: 전역객체 또는 window(frame)을 제어하기 위한 객체


2. DOM(window.document): 웹 페이지에 있는 문서(태그<body>, <img> 등))를 제어한다. 


3. BOM: 현재 이 웹브라우저가 가리키는 URL이나, 경고창을 띄운다거나 하는 등의 window 객체의 프로퍼티에 저장되어 있다.


4. JavaScriptCore: 자바스크립트라는 언어를 통해서 브라우저나, node.js, 구글 스프레시트 등의 다양한 호스트 환경을 제어할 수 있다. 그 호스트 환경이 무엇이든 간에 공통으로 사용할 수 있는 것이다. 

     --> 공통으로 사용할 수 있는 언어가 바로 JavaScriptCore이다.

ex.) node.js에서는 DOM이나 BOM이 적용되지 않는다.


1. BOM(Browser Object Model)

웹페이지의 내용을 제외한 브라우저의 각종 요소들을 객체화시킨 것이다. 전역객체 Window의 프로퍼티(window.document 제외)에 속한 객체들이 이에 속한다.

BOM은 전역객체인 Window의 프로퍼티와 메소드들을 통해서 제어할 수 있다. 따라서 BOM은 Window 객체의 프로퍼티와 메소드의 사용법을 배우는 것이라고 해도 과언이 아닐 것이다.

<!DOCTYPE html>

<html>

<body>

<input type="button" onclick="alert(window.location)" value="alert(window.location)" />

<input type="button" onclick="window.open('bom.html')" value="window.open('bom.html')" />

</body>

</html>


2. DOM (Document Object Model)

웹페이지의 내용을 제어한다. window 객체의 프로퍼티인 document 프로퍼터에 할당된 Document 객체가 이러한 작업을 담당한다.

Window 객체가 창을 의미한다면 Document 객체는 윈도우에 로드된 문서를 의미한다고 할 수 있다. 

Document 객체의 프로퍼티는 문서 내의 주요 엘리먼트에 접근할 수 있는 객체를 제공한다.

<!DOCTYPE html>

<html>

<body>

<img src="https://s3-ap-northeast-1.amazonaws.com/opentutorialsfile/course/94.png" />

<img src="https://s3-ap-northeast-1.amazonaws.com/opentutorialsfile/course/94.png" />

<img src="https://s3-ap-northeast-1.amazonaws.com/opentutorialsfile/course/94.png" />

<img src="https://s3-ap-northeast-1.amazonaws.com/opentutorialsfile/course/94.png" />

<img src="https://s3-ap-northeast-1.amazonaws.com/opentutorialsfile/course/94.png" />

<script>

// body 객체

console.log(document.body);

// 이미지 객체들의 리스트

console.log(document.images);

</script>

</body>

</html>


또한 특정한 엘리먼트의 객체를 획득할 수 있는 메소드도 제공한다.

<!DOCTYPE html>

<html>

<body>

<img src="https://s3-ap-northeast-1.amazonaws.com/opentutorialsfile/course/94.png" />

<img src="https://s3-ap-northeast-1.amazonaws.com/opentutorialsfile/course/94.png" />

<img src="https://s3-ap-northeast-1.amazonaws.com/opentutorialsfile/course/94.png" />

<img src="https://s3-ap-northeast-1.amazonaws.com/opentutorialsfile/course/94.png" />

<img src="https://s3-ap-northeast-1.amazonaws.com/opentutorialsfile/course/94.png" />

<script type="text/javascript">

// body 객체

console.log(document.getElementsByTagName('body')[0]);

// 이미지 객체들의 리스트

console.log(document.getElementsByTagName('body'));

</script>

</body>

</html>


'WebFont-end > JavaScript' 카테고리의 다른 글

[JavsScript] 제어 대상을 찾기  (0) 2014.12.21
[JavaScript] 전역객체 window  (0) 2014.12.21
[JavaScript] arguments(유사 배열 객체)  (0) 2014.12.21
[JavaScript] 클로저  (1) 2014.12.21
[JavaScript] 유효범위  (0) 2014.12.21

[JavaScript] arguments(유사 배열 객체)

arguments(유사 배열 객체)


argument라는 객체는 함수 안에서 함수의 여러가지 정보를 담고있는 특히 인자의 정보를 담고 있는 객체이다.(사용법이 배열과 유사)

함수에는 arguments라는 변수에 담긴 숨겨진 유사 배열이 있다. 이 배열에는 함수를 호출할 때 입력한 인자가 담겨있다. 

--> 몇 개의 인자가 있는지 알 수 있다, sum()으로 들어온 특정자리수의 값을 알수 있다.


function sum(){// 매개변수가 없다.

    var i, _sum = 0;    

    for(i = 0; i < arguments.length; i++){

    // argments는 약속되어 있는 특수한 변수명(argument라는 배열이 담겨있다.) 역할은 사용자가 전달한 인자가 argments 객체에 있다. 그러면 이 객체를 통해서 사용자가 전달한 인자에 

    // 접근할 수 있는 기능을 제공한다. sum()이 전달한 인자 개수를 알 수 있다.--> 사용자가 전달한 인자 수 만큼 for문의 루프를 돌린다.

        document.write(i+' : '+arguments[i]+'<br />');

        _sum += arguments[i];

    }   

    return _sum;

}

document.write('result : ' + sum(1,2,3,4));// 함수 정의 문장에 매개변수 선언 되어 있지 않지만 인자 수 상관 없다.

실행 결과)

0 : 1

1 : 2

2 : 3

3 : 4

result : 10

함수 sum은 인자로 전달된 값을 모두 더해서 리턴하는 함수다. 

그런데 1행처럼 함수 sum은 인자에 대한 정의하가 없다. 하지만 마지막 라인에서는 4개의 인자를 함수 sum으로 전달하고 있다. 

함수의 정의부분에서 인자에 대한 구현이 없음에도 인자를 전달 할 수 있는 것은 왜 그럴까? 그것은 arguments라는 특수한 배열이 있기 때문이다.


arguments는 함수안에서 사용할 수 있도록 그 이름이나 특성이 약속되어 있는 일종의 배열이다. 

arguments[0]은 함수로 전달된 첫번째 인자를 알아낼 수 있다.arguments.length를 이용해서 함수로 전달된 인자의 개수를 알아낼 수도 있다. 

이러한 특성에 반복문을 결합하면 함수로 전달된 인자의 값을 순차적으로 가져올 수 있다. 그 값을 더해서 리턴하면 인자로 전달된 값에 대한 총합을 구하는 함수를 만들 수 있다.


arguments는 사실 배열은 아니다. 실제로는 arguments 객체의 인스턴스다.


1. 매개변수의 수

매개변수와 관련된 두가지 수가 있다. 하나는 함수.length, 다른 하나는 arguments.length이다. 

함수.length는 함수로 전달된 실제 인자의 수를 의미하고, arguments.length는 함수에 정의된 인자의 수를 의미한다. 


function zero(){

    console.log(

        'zero.length', zero.length,// 0

        'arguments', arguments.length// 0

    );

}

function one(arg1){

    console.log(

        'one.length', one.length, // 1 --> 함수 정의한 매개변수(인수) 개수

        'arguments', arguments.length // 2 --> 함수 호출시 인자 개수

    );

}

function two(arg1, arg2){

    console.log(

        'two.length', two.length,

        'arguments', arguments.length

    );

}

zero(); // zero.length 0 arguments 0 

one('val1', 'val2');  // one.length 1 arguments 2 

two('val1');  // two.length 2 arguments 1

실행결과)

zero.length 0 arguments 0

VM123:9 one.length 1 arguments 2

VM123:15 two.length 2 arguments 1



'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] 전역객체 window  (0) 2014.12.21
[JavaScript] Object Model  (0) 2014.12.21
[JavaScript] 클로저  (1) 2014.12.21
[JavaScript] 유효범위  (0) 2014.12.21
[JavaScript] Object  (0) 2014.12.07

[JavaScript] 클로저


클로저


클로저(closure)는 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것을 가르킨다. 클로저는 자바스크립트를 이용한 고난이도의 테크닉을 구사하는데 필수적인 개념으로 활용된다.  


1. 내부함수

자바스크립트는 함수 안에서 또 다른 함수를 선언할 수 있다. 아래의 예제를 보자. 결과는 경고창에 coding everybody가 출력될 것이다.

function outter(){// 외부 함수

    function inner(){ //내부 함수

        var title = 'coding everybody'; 

        alert(title);

    }

    inner();

}

outter();

실행결과)

coding everybody

위의 예제에서 함수 outter의 내부에는 함수 inner가 정의 되어 있다. 함수 inner를 내부 함수라고 한다.


내부함수는 외부함수의 지역변수에 접근할 수 있다.  이것이 바로 클로저이다. 아래의 예제를 보자.

function outter(){

    var title = 'coding everybody';

    function inner(){        

        alert(title);

    }

    inner();

}

outter();

실행결과)

coding everybody

위의 예제는 내부함수 inner에서 title을 호출(4행)했을 때 외부함수인 outter의 지역변수에 접근할 수 있음을 보여준다.


2. 클로저


클로저(closure)는 내부함수와 밀접한 관계를 가지고 있는 주제다. 내부함수는 외부함수의 지역변수에 접근 할 수 있는데 외부함수의 실행이 끝나서 외부함수가 소멸된 이후(return)에도 내부함수가 외부함수의 변수에 접근 할 수 있다. 

이러한 메커니즘을 클로저라고 한다. 아래 예제는 이전의 예제를 조금 변형한 것이다.

function outter(){

    var title = 'coding everybody';  

    return function(){ // return했다면 그 함수는 생을 마감했다는 것이다.       

        alert(title);// title은 외부함수에 존재하는 값이다.

    }

}

inner = outter();//outter라는 함수가 생을 마감했음에도 불구하고

inner();

실행결과)

coding everybody

예제의 실행순서를 주의깊게 살펴보자. 7행에서 함수 outter를 호출하고 있다. 

그 결과가 변수 inner에 담긴다. 그 결과는 이름이 없는 함수다. 실행이 8행으로 넘어오면 outter 함수는 실행이 끝났기 때문에 이 함수의 지역변수는 소멸되는 것이 자연스럽다. 

하지만 8행에서 함수 inner를 실행했을 때 coding everybody가 출력된 것은 외부함수의 지역변수 title이 소멸되지 않았다는 것을 의미한다. (title은 외부함수의 지역변수이다.)

클로저란 내부함수가 외부함수의 지역변수에 접근 할 수 있고, 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는 특성을 의미한다.


조금 더 복잡한 아래 예제를 살펴보자. 아래 예제는 클로저를 이용해서 영화의 제목을 저장하고 있는 객체를 정의하고 있다. 

function factory_movie(title){ // 매개변수는 함수 안에서 지역변수로 사용되기 때문에 지역변수이다.

    return {

        get_title : function (){// 여기 메소드들은 factory_movie의 내부함수라고 보면된다.

// 변수 가져오기는 get_title을 통해서만

            return title;// factory_movie의 인자인 title이다.

        },

        set_title : function(_title){

// 변수 수정하는 것은 set_title을 통해서만 --> 보다 변수를 안전하게 사용할 수 있다.

            title = _title

        }

    }

}

ghost = factory_movie('Ghost in the shell'); 

matrix = factory_movie('Matrix');

 

alert(ghost.get_title()); 

alert(matrix.get_title());

// 각각 get_title()이라는 메소드가 접근하는 외부함수의 지역변수에 담겨있는 값이 서로 다르다.

ghost.set_title('공각기동대');

 

alert(ghost.get_title());

alert(matrix.get_title());

실행결과)

Ghost in the shell -> Matrix -> 공각기동대 -> Matrix 


위의 예제를 통해서 알 수 있는 것들을 정리해보면 아래와 같다.

1) 클로저는 객체의 메소드에서도 사용할 수 있다. 위의 예제는 함수의 리턴값으로 객체를 반환하고 있다. 

이 객체는 메소드 get_title과 set_title을 가지고 있다. 이 메소드들은 외부함수인 factory_movie의 인자값으로 전달된 지역변수 title을 사용하고 있다.


2) 동일한 외부함수 안에서 만들어진 내부함수나 메소드는 외부함수의 지역변수를 공유한다. 17행에서 실행된 set_title은 외부함수 factory_movie의 지역변수 title의 값을 '공각기동대'로 변경했다. 19행에서 ghost.get_title();의 값이 '공각기동대'인 것은 set_movie와 get_movie 함수가 title의 값을 공유하고 있다는 의미다.


3) 그런데 똑같은 외부함수 factory_movie를 공유하고 있는 ghost와 matrix의 get_title의 결과는 서로 각각 다르다. 그것은 외부함수가 실행될 때마다 새로운 지역변수를 포함하는 클로저가 생성되기 때문에 ghost와 matrix는 서로 완전히 독립된 객체가 된다.


4) factory_movie의 지역변수 title은 2행에서 정의된 객체의 메소드에서만 접근 할 수 있는 값이다. 이 말은 title의 값을 읽고 수정 할 수 있는 것은 factory_movie 메소드를 통해서 만들어진 객체 뿐이라는 의미다. JavaScript는 기본적으로 Private한 속성을 지원하지 않는데, 클로저의 이러한 특성을 이용해서 Private한 속성을 사용할 수 있게된다.


cf.)

Private 속성은 객체의 외부에서는 접근 할 수 없는 외부에 감춰진 속성이나 메소드를 의미한다. 이를 통해서 객체의 내부에서만 사용해야 하는 값이 노출됨으로서 생길 수 있는 오류를 줄일 수 있다. 

자바와 같은 언어에서는 이러한 특성을 언어 문법 차원에서 지원하고 있다. 아래의 예제는 클로저와 관련해서 자주 언급되는 예제다. 

var arr = [];

for(var i = 0; i < 5; i++){

    arr[i] = function(id){

        return function(){

            return id;

        }

    }

}

for(var index in arr) {

    console.log(arr[index]());

}

실행결과)

1

2

3

4

5

5

5

5

5

5


위의 코드는 아래와 같이 변경해야 한다.

var arr = [];

for(var i = 0; i < 5; i++){

    arr[i] = function(id) {

        return function(){

            return id;

        }

    }(i);

}

for(var index in arr) {

    console.log(arr[index]());

}

실행결과)

0

1

2

3

4


※ 클로저 참고

https://developer.mozilla.org/ko/docs/JavaScript/Guide/Closures

http://ejohn.org/apps/learn/#48

http://blog.javarouka.me/2012/01/javascripts-closure.html

'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] Object Model  (0) 2014.12.21
[JavaScript] arguments(유사 배열 객체)  (0) 2014.12.21
[JavaScript] 유효범위  (0) 2014.12.21
[JavaScript] Object  (0) 2014.12.07
[JavaScript] prototype  (0) 2014.12.07

[JavaScript] 유효범위


유효범위


유효범위(Scope)는 변수의 수명을 의미한다. 

var vscope = 'global';// 전역 변수

function fscope(){

    alert(vscope);

}

fscope();

실행결과)

global


함수 밖에서 변수를 선언하면 그 변수는 전역변수가 된다. 전역변수는 에플리케이션 전역에서 접근이 가능한 변수다. 다시 말해서 어떤 함수 안에서도 그 변수에 접근 할 수 있다. 그렇기 때문에 함수 fscope 내에서 vscope를 호출 했을 때 함수 밖에서 선언된 vscope의 값 global이 반환된 것이다. 

var vscope = 'global';

function fscope(){

    var vscope = 'local';// 로컬 변수

    alert('함수안 '+vscope);//local

}

fscope();

alert('함수밖 '+vscope);//grobal

실행결과)

함수 안: local 

함수 밖: global


즉 함수 안에서 변수 vscope을 조회(4행) 했을 때 함수 내에서 선언한 지역변수 vscope(3행)의 값인 local이 사용되었다. 하지만 함수 밖에서 vscope를 호출(7행) 했을 때는 전역변수 vscope(1행)의 값인 global이 사용된 것이다. 즉 지역변수의 유효범위는 함수 안이고, 전역변수의 유효범위는 에플리케이션 전역인데, 같은 이름의 지역변수와 전역변수가 동시에 정의되어 있다면 지역변수가 우선한다는 것을 알 수 있다. 아래 예제를 보자. 결과는 모두 local이다.


var vscope = 'global';

function fscope(){

    vscope = 'local'; // 전역 변수

    alert('함수안='+vscope); //local

}

fscope();

alert('함수밖='+vscope); //grobal

실행결과)

함수안=local

함수밖=local

// local(전역변수인 vscope를 변경한 것이므로)


var vscope = 'global';

function fscope(){

    var vscope = 'local';

    vscope = 'local';// 지역변수가 변경

    alert('함수안='+vscope);

}

fscope();

alert('함수밖='+vscope);

실행결과)

함수안=local

함수밖=global


함수밖에서도 vscope의 값이 local인 이유는 무엇일까? 그것은 함수 fscope의 지역변수를 선언할 때 var를 사용하지 않았기 때문이다. var를 사용하지 않은 지역변수는 전역변수가 된다. 따라서 3행은 전역변수의 값을 local로 변경하게 된 것이다. var을 쓰는 것과 쓰지 않는 것의 차이를 이해해야 한다.


전역변수는 사용하지 않는 것이 좋다. 여러가지 이유로 그 값이 변경될 수 있기 때문이다. 함수 안에서 전역변수를 사용하고 있는데, 누군가에 의해서 전역변수의 값이 달라졌다면 어떻게 될까? 함수의 동작도 달라지게 된다. 이것은 버그의 원인이 된다. 또한 함수를 다른 에플리케이션에 이식하는데도 어려움을 초래한다. 함수의 핵심은 로직의 재활용이라는 점을 상기하자. 변수를 선언할 때는 꼭 var을 붙이는 것을 습관화해야 한다. 전역변수를 사용해야 하는 경우라면 그것을 사용하는 이유를 명확히 알고 있을 때 사용하도록 하자.


1. 유효범위의 효용

아래 두개의 예제는 변수 i를 지역변수로 사용했을 때와 전역변수로 사용했을 때의 차이점을 보여준다. 전역변수는 각기 다른 로직에서 사용하는 같은 이름의 변수값을 변경시켜서 의도하지 않은 문제를 발생시킨다.

(1) 지역변수의 사용

function a (){

    var i = 0;// i는 지역변수

}

for(var i = 0; i < 5; i++){

    a();

    document.write(i);

}

실행결과)

01234


(2) 전역변수의 사용

본 예제는 무한반복을 발생시킨다. for문 안의 i값이 전역변수 

function a (){

    i = 0;// i는 전역변수

}

for(i = 0; i < 5; i++){

    a();

    document.write(i);

}


불가피하게 전역변수를 사용해야 하는 경우는 하나의 객체를 전역변수로 만들고 객체의 속성으로 변수를 관리하는 방법을 사용한다.

var MYAPP = {} // MAYAPP이라는 전역변수에다 다 집어 넣음

MYAPP.calculator = { // 객체안의 속성의 값으로 다시 객체를 선언

    'left' : null,

    'right' : null

}

MYAPP.coordinate = {

    'left' : null,

    'right' : null

}

 

MYAPP.calculator.left = 10;

MYAPP.calculator.right = 20;

function sum(){

    return MYAPP.calculator.left + MYAPP.calculator.right;

}

document.write(sum());

실행결과)

30 


전역변수를 사용하고 싶지 않다면 아래와 같이 익명함수를 호출함으로서 이러한 목적을 달성할 수 있다.

(function(){

    var MYAPP = {}

    MYAPP.calculator = {

        'left' : null,

        'right' : null

    }

    MYAPP.coordinate = {

        'left' : null,

        'right' : null

    }

    MYAPP.calculator.left = 10;

    MYAPP.calculator.right = 20;

    function sum(){

        return MYAPP.calculator.left + MYAPP.calculator.right;

    }

    document.write(sum());

}())

실행결과)

30 

함수를 정의한 후에 바로 호출할 때 괄호 사용(익명함수 사용이유) -->의미: MYAPP이라는 변수는 함수안에서 사용되는 변수로서 함수의 지역변수가 된다.

이러한 방식은 JQuery에서 많이 사용하는 방식


function myappfn(){

    var MYAPP = {}

    MYAPP.calculator = {

        'left' : null,

        'right' : null

    }

    MYAPP.coordinate = {

        'left' : null,

        'right' : null

    }

    MYAPP.calculator.left = 10;

    MYAPP.calculator.right = 20;

    function sum(){

        return MYAPP.calculator.left + MYAPP.calculator.right;

    }

    document.write(sum());

}

myappfn(); //MYAPP은 전역변수이다.

실행결과)

30 

위와 같은 방법은 자바스크립트에서 로직을 모듈화하는 일반적인 방법이다. 


2. 유효범위의 대상 (함수)

자바스크립트는 함수에 대한 유효범위만을 제공한다. 많은 언어들이 블록(대체로 {,})에 대한 유효범위를 제공하는 것과 다른 점이다. 

for(var i = 0; i < 1; i++){

    var name = 'coding everybody';

}

alert(name);//유효 범위 밖에서도 가능

실행결과)

coding everybody


cf.) 자바에서는 아래의 코드는 허용되지 않는다. name은 지역변수로 for 문 안에서 선언 되었는데 이를 for문 밖에서 호출하고 있기 때문이다.

for(int i = 0; i < 10; i++){

    String name = "egoing";

}

System.out.println(name); //console.log()와 같다.

자바스크립트의 지역변수는 함수에서만 유효하다.


3. 정적 유효범위

자바스크립트는 함수가 선언된 시점에서의 유효범위를 갖는다. 이러한 유효범위의 방식을 정적 유효범위(static scoping), 혹은 렉시컬(lexical scoping)이라고 한다. 

var i = 5;

 

function a(){

    var i = 10;

    b();

}


function b(){

    document.write(i);//지역변수가 없으면 전역변수를 찾게된다.

}

a();

실행 결과)

5

동적 유효범위: 사용되는 대상에 따라서 그 대상이 가지고 있는 변수에 접근할 수 있다.

정적 유효범위: 사용될 때가 아니고 정의(그 시점)될 때의 전역변수가 사용되게 된다. b는 누구에게 사용될 지 모른다. 누가 사용하든 똑같은 범위이다.


'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] arguments(유사 배열 객체)  (0) 2014.12.21
[JavaScript] 클로저  (1) 2014.12.21
[JavaScript] Object  (0) 2014.12.07
[JavaScript] prototype  (0) 2014.12.07
[JavaScript] 상속  (0) 2014.12.07

[JavaScript] Object


Object


Object 객체는 객체의 가장 기본적인 형태를 가지고 있는 객체이다. 다시 말해서 아무것도 상속받지 않는 순수한 객체다. 자바스크립트에서는 값을 저장하는 기본적인 단위로 Object를 사용한다. 

var grades = {'test1': 10, 'test2': 6, 'test3': 80};

동시에 자바스크립트의 모든 객체는 Object 객체를 상속 받는데, 그런 이유로 모든 객체는 Object 객체의 프로퍼티를 가지고 있다.

Object의 prototype은 모든 객체의 prototype이 된다.

Object가 가지고 있는 prototype는 모든 객체가 사용할 수 있는 기능이다. 즉, 모든 객체가 공통적으로 사용할 기능이 있다면 Object의 prototype으로 지정해 쓸 것이다. 

모든 객체가 가지고 있었으면 하는 기능이 있다면 개발자가 기능을 추가할 수 있다.

또한 Object 객체를 확장하면 모든 객체가 접근할 수 있는 API를 만들 수 있다. 아래는 Object 객체를 확장한 사례다.


- Object.메소드() 와 Object.prototype.메소드()의 차이


Object.keys(arr); --> Object.keys=function(){ }


Object.protptype.toString() --> Object.prototype.toString = function(){ }

메소드가 프로토타입 소속이라는 것은 new한 순간 객체를 만들고 그 객체는 포로토타입이라는 특수한 프로퍼티에에 저장된 객체를 원형으로 하는 객체가 생성된다.

그렇게 생성된 객체는 toString()을 사용할 수 있게 된다.


Object는 자바스크립트의 공통 조상이다. 그래서 Object중에 ptototype이 중간에 낀 메소드들은 모든 객체들이 상속받고 있는 공통의 기능이 된다.

개발자가 만드는 자바스크립트 웹어플리케이션에서 모든 객체들이 공통적으로 가지고 있어야 하는 기능이 있다면 Object의 prototype 객체를 수정하여 그러한 기능을 만들 수 있다.

Object.prototype.contain = function(needle) {//어떠한 메소드를 갖게 하고 싶다면  

    for(var name in this){//메소드가 소속되어 있는 객체 -->this

        if(this[name] === needle){// 객체들은 for-in문을 사용하여 하나하나 꺼내서 볼 수 있다.

            return true;

        }

    }

    return false;

}

var o = {'name':'test1', 'city':'test2'}

console.log(o.contain('test1'));//contain은 value가 존재하는지 체크-->true or false

var a = ['test1','test2','test3'];

console.log(a.contain('test2'));

그런데 Object 객체는 확장하지 않는 것이 바람직하다. 왜냐하면 모든 객체에 영향을 주기 때문이다. 


확장 후에 아래 코드를 실행해보자.

for(var name in o){

    console.log(name);  

}

결과)

name

city

contain

--> prototype의 메소드인 contain까지 포함되는 결과를 낳게 된다.(원래 var o = {'name':'test1', 'city':'Seoul'})


확장한 프로퍼티인 contain이 포함되어 있다. 객체가 기본적으로 가지고 있을 것으로 예상하고 있는 객체 외에 다른 객체를 가지고 있는 것은 개발자들에게 혼란을 준다. 

이 문제를 회피하기 위해서는 프로퍼티의 해당 객체의 소속인지를 체크해볼 수 있는 hasOwnProperty를 사용하면 된다. 

for(var name in o){

    if(o.hasOwnProperty(name))

        console.log(name);  

}

결과)

name

city

hasOwnProperty는 인자로 전달된 속성의 이름이 객체의 속성인지 여부를 판단한다. 만약 prototype으로 상속 받은 객체라면 false(contain은 부모로부터 상속받은 프로퍼티이다.)가 된다. 

--> 객체의 직접적인 소유인 체크



'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] 클로저  (1) 2014.12.21
[JavaScript] 유효범위  (0) 2014.12.21
[JavaScript] prototype  (0) 2014.12.07
[JavaScript] 상속  (0) 2014.12.07
[JavaScript] this  (0) 2014.12.07

[JavaScript] prototype


prototype


한국어로 원형이다. 자바스크립트는 prototype를 통해 상속 기능을 제공한다.


1. prototype

그럼 prototype이란 무엇인가? 한국어로는 원형정도로 번역되는 prototype은 말 그대로 객체의 원형이라고 할 수 있다. 함수는 객체다. 그러므로 생성자로 사용될 함수도 객체다. 객체는 프로퍼티를 가질 수 있는데 prototype이라는 프로퍼티는 그 용도가 약속되어 있는 특수한 프로퍼티다. prototype에 저장된 속성들은 생성자를 통해서 객체가 만들어질 때 그 객체에 연결된다. 


function Ultra(){}

Ultra.prototype.ultraProp = true;

 

function Super(){}

Super.prototype = new Ultra();

  

function Sub(){}

Sub.prototype = new Super();// Super 생성자가 만든 객체가 new Super()에 리턴된다.


var o = new Sub();

console.log(o.ultraProp);//ultraProp이라는 값은 Sub의 조부모인 Ultra가 가지고 있다.

결과) 

true

생성자는 기본적으로 함수이다. new를 붙이면 일반함수에서 생성자로 바뀐다.

var o = new Sub();에서 새로운 객체를 만들어서

o가 리턴값이다.--> o라는 변수안에 생성자를 통해 만들어진 객체가 만들어 진다. 


cf.) new를 통해 객체를 만드는 이유

객체를 생성하고 나서 그 객체가 가지고 있는 메소드, 프로퍼티를 가지고 쥐어주기 때문이다.


우리가 얻고자하는 객체의 원형, 즉, 객체가 어떠한 객체 있고 어떠한 메소드와 프로터티를 가지고 있다는 그 객체의 원형은 어딘가에 저장되어 있는데 그 위치는 prototype이라고 하는 프로퍼티에 저장되어 있다.

즉, Sub라고 하는 함수는 객체이기 때문에 프로퍼티를 가질 수 있다. 그 프로퍼티가 prototype가 있어서 그 prototype이라는 프로퍼티에는 객체가 정의되어 있다.(Sub.prototype= new Super();)

그 protpype이라는 프로퍼티에는 어떠한 객체가 들어가 있다. 나중에 var o = new Sub();를 통해 생성자를 호출하게 되면 자바스크립트는 생성자 함수의 prototype의 프로퍼티에 저장되어 있는 객체(Sub.prototype)를 꺼내서 그것을 리턴해 준다.


function Ultra(){}

Ultra.prototype.ultraProp = true;

 

function Super(){}

Super.prototype = new Ultra();

 

function Sub(){}

Sub.prototype = new Super();

 

var o = new Sub();

o.ultraProp = 1;// 정의한 바 있으면 이 값을 찍는다.

console.log(o.ultraProp);

결과) 

1


function Ultra(){}

Ultra.prototype.ultraProp = true;

 

function Super(){}

Super.prototype = new Ultra();

 

function Sub(){}

Sub.prototype = new Super();

Aub.prototype.ultraProp = 2;


var o = new Sub();// Sub 생성자를 호출해서 그 객체에 prototype를 찾아서 있다면 그 값을 준다.

console.log(o.ultraProp);

결과)

2


function Ultra(){}

Ultra.prototype.ultraProp = true;

 

function Super(){}

var t = new Ultra();

t.ultraProp = 4;// 이 문장을 주석하면 결과는 true이다.

Super.prototype = t;// 


function Sub(){}

Sub.prototype = new Super();

 

var o = new Sub();

console.log(o.ultraProp);

결과)

4


생성자 Sub를 통해서 만들어진 객체 o가 Ultra의 프로퍼티 ultraProp에 접근 가능한 것은 prototype 체인으로 Sub와 Ultra가 연결되어 있기 때문이다. 내부적으로는 아래와 같은 일이 일어난다.

1 객체 o에서 ultraProp를 찾는다.

2 없다면 Sub.prototype.ultraProp를 찾는다.

3 없다면 Super.prototype.ultraProp를 찾는다.

4 없다면 Ultra.prototype.ultraProp를 찾는다.

prototype는 객체와 객체를 연결하는 체인의 역할을 하는 것이다. 이러한 관계를 prototype chain이라고 한다.


Super.prototype = Ultra.prototype 으로하면 안된다. 이렇게하면 Super.prototype의 값을 변경하면 그것이 Ultra.prototype도 변경하기 때문이다. (부모 객체에 영향을 준다.--> 자식에게 반영된 일들이 부모에게 영향을 주는 꼴이된다.)

Super.prototype = new Ultra();는 Ultra.prototype의 원형으로 하는 객체가 생성되기 때문에 new Ultra()를 통해서 만들어진 객체에 변화가 생겨도 Ultra.prototype의 객체에는 영향을 주지 않는다.



'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] 유효범위  (0) 2014.12.21
[JavaScript] Object  (0) 2014.12.07
[JavaScript] 상속  (0) 2014.12.07
[JavaScript] this  (0) 2014.12.07
[JavaScript] 생성자와 new  (0) 2014.12.07

[JavaScript] 상속


상속


1. 상속(inheritance)이란?

객체는 연관된 로직들로 이루어진 작은 프로그램이라고 할 수 있다. 상속은 객체의 로직을 그대로 물려 받는 또 다른 객체를 만들 수 있는 기능을 의미한다. 

단순히 물려받는 것이라면 의미가 없을 것이다. 기존의 로직을 수정하고 변경해서 파생된 새로운 객체를 만들 수 있게 해준다. 

상속 받은 객체가 부모 객체의 어떠한 기능은 제외하고 어떠한 기능은 추가해서 자신의 맥락에 맞게 부모의 객체의 로직을 재활용하면서 또 그 맥락에 맞는 로직을 제거하거나 추가하면서 재활용할 수 있다.


아래 코드는 이전 시간에 살펴본 코드다.

function Person(name){

    this.name = name;

    this.introduce = function(){

        return 'My name is '+this.name; 

    }   

}

var p1 = new Person('sibal');

document.write(p1.introduce()+"<br />");

결과)

My name is sibal

프로퍼티를 셋팅하는 방법으로 생성자를 사용함


생성자 말고도 다른 방법으로도 프로퍼티를 셋팅할 수 있다.

위의 코드를 아래와 같이 바꿔보자.

function Person(name){

    this.name = name;

}

Person.prototype.name=null;// Person은 객체

Person.prototype.introduce = function(){

    return 'My name is '+this.name; 

}

var p1 = new Person('egoing');

document.write(p1.introduce()+"<br />");

결과는 같다. 하지만 상속을 위한 기본적인 준비를 마쳤다. 이제 상속을 해보자. 


상속의 목적: 상위 객체의 코드를 물려받아 하위 객체에 없는 프로퍼티도 사용할 수 있게 하기 위함이다.

function Person(name){

    this.name = name;

}

Person.prototype.name=null;

Person.prototype.introduce = function(){

    return 'My name is '+this.name; 

}

 

function Programmer(name){

// 생성자--> Programmer를 통해서 만든 객체가 Person을 통해서 만든 객체와 동일한 기능을 가지도록 하는 것이 목적

    this.name = name;

    //사람이 가지고 있는 프로퍼티

}

Programmer.prototype = new Person();

// Person이라는 객체는 prototype의 값이 되는 것이다.--> 어떠한 객체를 상속받고 싶다면 그 객체를 생성자의 prototype에 할당을 시킨다.

// Programmer가 Person을 상속할 수 있었던 이유 

// new를 통해 객체가 생성되는데 자바스크립트에서는 prototype라는 속성을 생성자 함수가 가지고 있는 지를 확인한다. 그 생성자 함수안에 들어있는 

// 객체와 똑같은 객체를 만들어서 생성자의 결과로 리턴한다.

// 그래서 new Person을 통해서 만든 객체는 prototype객체가 가지고 있는 name이라는 프로퍼티와 introduce라는 메소드(함수를 introduce에 대입)를 가지고 있는 객체가 프로토타입 안에 들어가 있기 때문에 new Person을 통해 만든 객체는 name과 introduce를 가지고 있는 객체가 된다.

 

var p1 = new Programmer('sibal');

// 객체을 생성(인자 전달)

// new Programmer를 통해서 객체화 시키면 자바스크립트는 이 Programmer라고 하는 생성자 함수가 가지고 있는 prototype이라고 하는 

// 프로퍼티값과 동일한 구조(객체)를 만들어서 리턴한 것이 p1이다.

// p1은 prototype라는 생성자의 프로퍼티에 들어있는 객체와 같은데 그 객체는 new Person 즉, Person이라는 생성자를 통해 만든 객체이기 때문에 

// 그 객체가 가지고 있는 name과 introduce도 가지고 있다. 그래서 코드를 물려받아 사용할 수 있다.

document.write(p1.introduce()+"<br />");

// Programmer라는 생성자 안에는 introduce라는 메소드가 정의되어 있지 않음--> Person 생성자에 정의되어 있음 

// --> Programmer에서 introduce를 사용할 수 있었던 이유는 이 Programmer가 intoduce를 상속하기 때문이다.

Programmer이라는 생성자를 만들었다. 그리고 이 생성자의 prototype과 Person의 객체를 연결했더니 Programmer 객체도 메소드 introduce를 사용할 수 있게 되었다. 

Programmer가 Person의 기능을 상속하고 있는 것이다. 단순히 똑같은 기능을 갖게 되는 것이라면 상속의 의의는 사라질 것이다. 부모의 기능을 계승 발전할 수 있는 것이 상속의 가치다.


function Person(name){

    this.name = name;

}

Person.prototype.name=null;

Person.prototype.introduce = function(){

    return 'My name is '+this.name; 

}

 

function Programmer(name){

    this.name = name;

}

Programmer.prototype = new Person();

Programmer.prototype.coding = function(){

    return "hello world";

}


function Designer(name){

    this.name = name;

}

Designer.prototype = new Person();

Designer.prototype.design = function(){

    return "beautiful!";

}

 

var p1 = new Programmer('sibal');

document.write(p1.introduce()+"<br />"); 

document.write(p1.coding()+"<br />");


var p2 = new Designer('leezche');

document.write(p2.introduce()+"<br />"); 

document.write(p2.design()+"<br />");

결과)

My name is sibal

hello world

Person 이라는 공통의 부모가 있고 Programmer와 Design이라는 객체가 Person을 상속받는다.

Programmer는 Person의 기능을 가지고 있으면서 Person이 가지고 있지 않은 기능인 메소드 coding을 가지고 있다. 




'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] Object  (0) 2014.12.07
[JavaScript] prototype  (0) 2014.12.07
[JavaScript] this  (0) 2014.12.07
[JavaScript] 생성자와 new  (0) 2014.12.07
[JavaScript] 함수의 호출  (0) 2014.12.07

[JavaScript] this


this


vo.) context: 의미가 고정적이지 않고 그것을 사용하는 상황에 따라 의미가 달라질수 있다. 가변적이다

this는 함수 내에서 함수 호출 맥락(context)를 의미한다. 맥락이라는 것은 상황에 따라서 달라진다는 의미인데 즉 함수를 어떻게 호출하느냐에 따라서 this가 가리키는 대상이 달라진다는 뜻이다. 

함수와 객체의 관계가 느슨한 자바스크립트에서 this는 이 둘을 연결시켜주는 실질적인 연결점의 역할을 한다.

this는 함수 안에서 사용할 수 있는 일종의 변수이면서 그 변수안에 값은 그 함수를 어떻게 호출하느냐에 따라서 달라진다.


1. 함수호출

함수를 호출했을 때 this는 무엇을 가르키는지 살펴보자. this는 전역객체인 window와 같다.

function func(){

    if(window === this){//"==="--> 정확하게 같은지 체크한다.

        document.write("window === this");

    }

}

func(); 

결과) 

window === this


cp.) 최상위 this

var abc = "Kim";

     window.def = " HJ";

     console.log(this.abc + "+" + this.def);

(function(){

console.log(this.abc + "+" + this.def);

})();

실행결과)

Kim+ HJ

Kim+ HJ


2. 메소드의 호출

객체의 소속인 메소드의 this는 그 객체를 가르킨다. 

var o = {

    func : function(){

        if(o === this){

            document.write("o === this");

        }

    }

}

o.func();   

결과)

o === this

이것을 통해 우리가 알 수 있는 것은 어떠한 객체안의 메소드에서 메소드를 호출하면 메소드가 소속되어 있는 객체를 this로 접근할 수 있다.


3. 생성자의 호출

아래 코드는 함수를 호출했을 때와 new를 이용해서 생성자를 호출했을 때의 차이를 보여준다.

함수 안에서 this라는 키워드는 그 함수가 소속되어 있는 객체를 가리킨다.

---> 이것이 기본 원칙이다. 그 함수가 누구의 소속(객체)이냐에 따라서 this의 값은 그 객체(소속)의 값을 가리킨다.

var funcThis = null; 

 

function Func(){ 

    funcThis = this;// var이 없으므로 전역 변수인 funcThis이다.--->this는 window

}

var o1 = Func();// Func는 일반함수이다.함수안에서의 this는 window를 가리킨다.

if(funcThis === window){

    document.write('window </br>');

}

 

var o2 = new Func();//비어있는 객체를 만들고 그 비어있는 만들어진 객체가 생성자 안에 this가 된다(this는 생성된 객체를 가리킨다.). new를 통해 호출했으므로 Func는 생성자이다. -->this는 o2

if(funcThis === o2){

    document.write('o2 </br>');

}

결과)

window 

o2


생성자는 빈 객체를 만든다. 그리고 이 객체내에서 this는 만들어진 객체를 가르킨다. 이것은 매우 중요한 사실이다. 

생성자가 실행되기 전까지는 객체는 변수에도 할당될 수 없기 때문에 this가 아니면 객체에 대한 어떠한 작업을 할 수 없기 때문이다. -->undefined

function Func(){

    document.write(o);

}

var o = new Func();

결과)

undefined


cp.) 생성자 this

var Abc = function Abc(msg) {

this.abc = msg;

this.method = function () {

console.log("method+" + this.abc);

}

}


var obj1 = new Abc("Hello");

var obj2 = new Abc("World");


// Hello 표시

console.log(obj1.abc);

// method+Hello 표시

obj1.method();


// World 표시

console.log(obj2.abc);

// method+World 표시

obj2.method();


// new를 안붙였기 때문에 Abc내 this는 전역 객체임

Abc("new가없음");

console.log(window.abc == "new가없음");

// method+new가없음!

window.method();

실행결과)

Hello

method+Hello

World

method+World

true

method+new가없음


4. 어떤 것에 소속된 this

소속된 개체를 가리킵니다.

var abc = {def:"HJ"};

abc.print1 = function() {

console.log(this.def);

};


// HJ 표시

abc.print1();


var func = function() {

console.log(this.def);

};

// window.def가 참조되어 undefined

func();


abc.print2 = func;

// this가 abc로 변경되어 HJ 표시

abc.print2();


// prototype시도

var Abc = function Abc(msg) {

this.message = msg;

};

Abc.prototype.print = function() {

console.log("prototype+" + this.message);

}

var obj = new Abc("Hello");

// prototype+Hello 표시

obj.print();

실행결과)

HJ

undefined

HJ

prototype+Hello


4. apply, call

함수의 메소드인 apply, call을 이용하면 this의 값을 제어할 수 있다. 

cf.) 함수도 객체이다.

var o = {}

var p = {}

function func(){

    switch(this){

        case o:

            document.write('o<br />');

            break;

        case p:

            document.write('p<br />');

            break;

        case window:

            document.write('window<br />');

            break;          

    }

}

func();

func.apply(o);

func.apply(p);

결과)

window

o

p

자바스크립트에서 함수는 일반적인 객체지향언어의 메소드보다 위상이 높다.(객체에 종속적이지 않다.) 

그럼에도 불구하고 함수를 어떻게 호출하느냐에 따라서 맥락적으로 함수는 어떠한 객체에 종속될 수도 있다.

this는 맥락에 따라 달라진다.


cf.) var o { }: 객체리터럴/ var o =new Object();

      var a =[1,2,3]/ var new Array(1,2,3)


'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] prototype  (0) 2014.12.07
[JavaScript] 상속  (0) 2014.12.07
[JavaScript] 생성자와 new  (0) 2014.12.07
[JavaScript] 함수의 호출  (0) 2014.12.07
[JavaScript] 콜백  (0) 2014.12.07

[JavaScript] 생성자와 new


생성자와 new


new를 붙이면 객체가 된다.


1. 객체

객체란 서로 연관된 변수와 함수를 그룹핑한 그릇이라고 할 수 있다. 객체 내의 변수를 프로퍼티(property) 함수를 메소드(method)라고 부른다. 객체를 만들어보자.

자바스크립트는 어느 객체지향언어와 같지 않다. 자바스크립트만의 독특한 체계를 가지고 있다. 자바스크립트 계열에 속하는 언어들은 prototypeBased 프로그래밍 언어이다.


자바스크립트 객체 : 전통적인 함수의 특징을 그대로 가지고 있지 않고 객체지향적인 문법 비슷하게 사용하면서 함수형 언어이다. 알면 알수록 난해하다. 하지만 자바스크립트가 추구하는 스타일은 자유롭고 유연하다.

엄격성, 규제(자바)가 깐깐하는 것과는 대비된다. 언어를 바라보는 넓어지는 기회로 삼자.


var person = {}//객체 생성(비어있는 객체)--> object라는 이름의 object를 만든다.

person.name = 'nimi';//name은 변수(프로퍼티)

person.introduce = function(){// 프로퍼티에 담겨있는 함수는 메소드라고 한다.(함수안에 담겨는 변수는 프로퍼티라고 한다./변수에 담겨있는 값이 함수라면 메소드라고 한다.)

    return 'My name is '+this.name;

}

document.write(person.introduce());

객체를 만드는 과정에 분산되어 있다. 객체를 정의 할 때 값을 셋팅하도록 코드를 바꿔보자.


var person = {

    'name' : 'nimi',

    'introduce' : function(){

        return 'My name is '+this.name;// this는 실행문장을 정의한 함수의 객체 --> person 변수가 담고 있는 객체 --> name은 egoing

    }

}

document.write(person.introduce());

만약 다른 사람의 이름을 담을 객체가 필요하다면 객체의 정의를 반복해야 할 것이다. 객체의 구조를 재활용할 수 있는 방법이 필요하다. 이 때 사용하는 것이 생성자다.


2. 생성자

생성자(constructor)는 객체를 만드는 역할을 하는 함수다. 자바스크립트에서 함수는 재사용 가능한 로직의 묶음이 아니라 객체를 만드는 창조자라고 할 수 있다.

함수가 객체의 시중을 드는 것이 아니라 객체를 창조하는 역할--> 자바와 헷갈리게 하는 요소

자바스크립트에서는 클래스가 없다. 자바는 클래스가 있다. 클래스 안에 생성자가 있음--> 객체 생성

자바스크립트는 생성자가 클래스에 소속하지 않아서 생성자는 그냥 함수에 불과하다. 그 함수에 new를 붙이면 그냥 객체를 만든다.--> 함수에 new를 붙이면 리턴값은 객체가 된다.


function Person(){}// 평범한 함수

var p = new Person(); // new 붙이고 함수 호출하면 ---> 함수가 아니라 생성자라 한다.(객체의 생성자)--> 비어있는 객체를 만들고 p에 반환  

p.name = 'nimi';

p.introduce = function(){// 프로퍼티에 익명함수를 넣게 되면 이 프로퍼티는 메소드라고 불리게 된다.

    return 'My name is '+this.name; 

}

document.write(p.introduce());

함수를 호출할 때 new을 붙이면 새로운 객체를 만든 후에 이를 리턴한다. 위의 코드는 새로운 객체를 변수 p에 담았다. 여러사람을 위한 객체를 만든다면 아래와 같이 코드를 작성해야 할 것이다. 


function Person(){}

var p1 = new Person();

p1.name = 'nimi';

p1.introduce = function(){

    return 'My name is '+this.name; 

}

document.write(p1.introduce()+"<br />");

 

var p2 = new Person();

p2.name = 'minaral';

p2.introduce = function(){

    return 'My name is '+this.name; 

}

document.write(p2.introduce());

별로 개선된 것이 없다. 


function Person(name){

    this.name = name;

    this.introduce = function(){

        return 'My name is '+this.name; 

    }   // 호출하면서 초기화 되기 때문에 한번만 선언해도 된다.

}

var p1 = new Person('nimi');

document.write(p1.introduce()+"<br />");

 

var p2 = new Person('minaral');

document.write(p2.introduce());

생성자 내에서 이 객체의 프로퍼티를 정의하고 있다. 이러한 작업을 초기화(생성자가 객체에 대한 초기화 작업을 한다.)객체가 가지고 있는 정보, 그 객체가 할 수 있는 일을 셋팅하는 것을 초기화 또는 init(initialize) 라고 한다. 이를 통해서 코드의 재사용성이 대폭 높아졌다.

코드를 통해서 알 수 있듯이 생성자 함수는 일반함수와 구분하기 위해서 첫글자를 대문자로 표시한다.


3. 자바스크립트 생성자의 특징

일반적인 객체지향 언어에서 생성자는 클래스의 소속이다. 하지만 자바스크립트에서 객체를 만드는 주체는 함수다. 함수에 new를 붙이는 것을 통해서 객체를 만들 수 있다는 점은 자바스크립트에서 함수의 위상을 암시하는 단서이면서 또 자바스크립트가 추구하는 자유로움을 보여주는 사례라고 할 수 있다.



'WebFont-end > JavaScript' 카테고리의 다른 글

[JavaScript] 상속  (0) 2014.12.07
[JavaScript] this  (0) 2014.12.07
[JavaScript] 함수의 호출  (0) 2014.12.07
[JavaScript] 콜백  (0) 2014.12.07
[JavaScript] 값으로서의 함수  (0) 2014.12.07