'Javascript'에 해당되는 글 112건

  1. 2012.03.06 아스키, EUC-KR(ASCII), UNICODE, UTF-8(UNICODE) 정의
  2. 2012.03.06 자바스크립트 URL 요청 - (javascript:)
  3. 2012.02.25 자바스크립트 메서드 빌려쓰기
  4. 2012.02.25 자바스크립트 상속 6
  5. 2012.02.23 자바스크립트 상속 5
  6. 2012.02.21 자바스크립트 상속 4
  7. 2012.02.21 자바스크립트 상속 3
  8. 2012.02.21 자바스크립트 상속 2
  9. 2012.02.21 자바스크립트 상속 1
  10. 2012.02.19 자바스크립트 method() 함수

아스키, EUC-KR(ASCII), UNICODE, UTF-8(UNICODE) 정의




- ASCII: 

1. 영문/숫자/기호 1글자는 1바이트, 한글/한자 1글자는 2바이트

2. 하나의 인코딩당, 영문과 또 다른 하나의 언어만 사용할 수 있습니다.

3. 하나의 파일에 여러 언어를 동시에 표현할 수 없습니다.

4. 컴퓨터 초창기부터 사용해 왔기에, 호환성이 좋습니다.

5. 웹페이지 작성에 사용 가능합니다.
 




- 한글 완성형 EUC-KR(ASCII) / ksc_c_5601-1987:

1.  영문/숫자/기호 1글자는 1바이트, 한글/한자 1글자는 2바이트

2. 영문, 한글, 한국에서 사용되는 한자만 표현. 즉, 특수 외국어 문자, 일본식/중국식
한자는 표현할 수 없습니다.


3. 하나의 파일에 여러 언어를 동시에 표현할 수 없습니다.

4. 컴퓨터 초창기부터 사용해 왔기에, 호환성이 좋습니다. 

5. 웹페이지 작성에 사용 가능합니다.




- UNICODE:

1.  영문/숫자/기호/한글/한자 1글자는 2바이트, 파일에 저장시에도 2바이트

2. 모든 언어가 표현 가능합니다.

3. 하나의 파일에 모든 언어를 표현할 수 있습니다. 단 각 언어에 대한 폰트가 설치되어 있어야 가능합니다.

4. 유니코드의 역사가 그리 길지 않기 때문에 호환성이 떨어집니다.

5. 웹페이지를 작성할 수 없습니다.

6. 자바스크립트는 문자 집합은 UNICODE로 이루어져 있습니다.




- UTF-8(UNICODE):

1.  영문/숫자/기호 1글자는 1바이트, 한글/한자 1글자는 3바이트, 파일에 저장시에도 3바이트

2. 모든 언어가 표현 가능합니다. 

3. 하나의 파일에 모든 언어를 표현할 수 있습니다. 단 각 언어에 대한 폰트가 설치되어 있어야 가능합니다.

4. 유니코드의 역사가 그리 길지 않기 때문에 호환성이 떨어집니다.

5. 웹페이지 작성에 사용 가능합니다. 

자바스크립트 URL 요청 - (javascript:)


자바스크립트 URL 요청이란?


보통 마크업 상에서 간단한 자바스크립트를 호출 시 아래와 같이 자바스크립트 URL 요청 방식을 사용하기도 합니다.

"하지만 이 방식은 웹 접근성 저하를 유발하므로 될 수 있으면 사용하지 않는 것이 좋습니다."


  1. <a href="javascript:alert('hello world1');">hello world1</a>
  2. <button onclick="javascript:alert('hello world2');">hello world2</button>
  3. <input type="button" value="hello world3" onclick="javascript:alert('hello world3');"></button>
 

위와 같은 작성 방식을 "javascript: URL 모조 프로토콜(pseudo protocol)"이라 하며, 자바스크립트 표현 식을 평가하고 그에 따른 결과를 출력할 수 있습니다.

코드는 프로토콜 지시자(javascript:)의 세미콜론으로 구분된 임의의 자바스크립트 코드로 작성됩니다.

브라우저는 이러한 URL 요청을 받으면 해당 자바스크립트 코드를 실행하며, 문자열로 반환되면 웹 브라우저에 문서로 출력됩니다.


테스트를 위하여 아래 나열된 코드를 브라우저의 주소창이나 A 태그를 활용하여 확인해 보시기 바랍니다.


  1. javascript:(function(){ alert(document.cookie); })(); // cookie
  2.  
  3. javascript:(function(){ alert(window.location.href); })(); // url
  4.  
  5. javascript:alert((function(){
  6.     return function(){
  7.         var x = 1
  8.           , y = 2;
  9.  
  10.  
  11.         return x + y;
  12.     }
  13. })()()); // 3
  14.  
  15.  
  16. javascript:(function(){
  17.     return function(){
  18.         var x = 1
  19.           , y = 2;
  20.  
  21.  
  22.         return x + y;
  23.     }
  24. })()(); // 3
  25.  
  26.  
  27. javascript:(function(){
  28.     return function(){
  29.         for (n in window.navigator)
  30.         {
  31.             if (n.toLowerCase() === 'useragent')
  32.             {
  33.                 alert(n);
  34.             }
  35.         }
  36.     }
  37. })()(); // useragent
 

자바스크립트 메서드 빌려쓰기


객체 메서드 빌려 쓰기

  1. function Parent(name){
  2.     this.name = name;
  3. };
  4.  
  5. Parent.prototype.substr = function(s, e){
  6.     return this.name.substr(s, e);
  7. }
  8.  
  9. function method(name){
  10.     this.name = name;
  11.     return this;
  12. }
  13.  
  14. method.prototype.getName = function(s, e){
  15.     // Parent 객체의 메서드 빌려쓰기.
  16.     return new Parent().substr.apply(this, [s, e]);
  17. }
  18.  
  19. alert(new Parent('jsk').substr(0, 1)); // j
  20. alert(new method('jsk').getName(1, 1)); // s

모듈을 작성하다보면 어떤 객체의 메서드 한 두 개만 마음에 드는 경우가 있습니다.
 
이 메서드들을 재사용 하고 싶지만, 해당 객체와 부모-자식 관계까지 만들고 싶지는 않을때
위같은 메서드 빌려쓰기 작성법을 이용하여 원하는 메서드만 골라서 사용할 수 있습니다.


  1. function f(){
  2.     var args = [].slice.call(arguments, 1, 3);
  3.  
  4.     return args;
  5. }
  6.  
  7. alert(f(1, 2, 3, 4)); // 2, 3

가장 대표적인 사례를 뽑자면, 위의 코드에서 처럼 함수의 arguments 객체와 [].slice 메서드를 빌려 원하는 매개변수를 골라내는 방법이 있습니다.

자바스크립트 상속 6


기타 상속 방식


  1. var Inherit = (function(){
  2.    
  3.     var Parent = {
  4.         name: 'test' ,
  5.         getName: function(){
  6.             return this.name;
  7.         }
  8.  
  9.     }
  10.  
  11.     function Child(){ ; };
  12.  
  13.     Child.prototype = Parent;
  14.     Child.prototype.constructor = Child;
  15.  
  16.     return new Child();
  17.  
  18. })();
  19.  
  20. alert(Inherit.getName()); // test
  21. alert(Inherit.constructor); // Child

1. Parent 객체를 생성 합니다.

2. Child 생성자 함수의 프로토타입 맴버에 Parent 객체를 추가 합니다.

 
3. new Child 객체를 반환 합니다.
 
4. 여기서 new Child 객체는 new Parent 객체의 맴버 모두(name, getName())를 상속
받습니다.


부모 객체를 생성자 함수가 아닌 객체 리터널 방식으로 생성하여 자식 객체에게 상속한
방법 입니다.

자바스크립트 상속 5


4. 클래스 방식 상속(프로토타입 공유)


  1. var Inherit = (function(){
  2.    
  3.     function Parent(name){
  4.         this.name = name || [1];
  5.         return this;
  6.     }
  7.  
  8.     Parent.prototype.getName = function(){
  9.         return this.name;
  10.     };
  11.  
  12.     function Child(){
  13.     };
  14.    
  15.  
  16.     Child.prototype = Parent.prototype;
  17.     // Child.prototype 맴버에 추가된 Parent.prototype으로 인해 Parent 생성자 함수로 변경된 Child.prototype.constructor 를 재설정해준다.
  18.     // (보통 정보성으로만 사용되는 프로퍼티이기 때문에 기능에는 거의 영향을 미치지 않는다.)
  19.     Child.prototype.constructor = Child;
  20.  
  21.     return new Child();
  22.  
  23. })();
  24.  
  25. alert(Inherit.getName); // getName()
  26. alert(Inherit.getName()); // undefined
  27.  
  28. alert(Inherit.constructor); // Child



1. Parent 생성자 함수에 인스턴스 맴버 name 속성을 추가 합니다.
 
2. Parent 생성자 함수에 프로토타입 맴버 getName 메서드를 추가 합니다.
 
4. Child 생성자 함수의 프로토타입 맴버에 Parent 생성자 함수의 프로토타입 맴버를
추가 합니다.
 
5. new Child 객체를 반환 합니다.
 
6. 여기서 new Child 객체는 new Parent 객체의 맴버(프로토타입) 모두(getName())를
상속 받습니다.



이전 포스트의 클래스 방식 상속은 모두 부모 생성자를 호출한것과 달리 이번에 살펴볼 상속 패턴은 부모 생성자를 호출하지 않습니다.
 
원칙적으로 객체 멤버에서 재사용될 멤버는 인스턴스 맴버가 아닌 프로토타입 맴버에 추가되어야 하며, 즉 상속 되어야 하는 모든 멤버들은 프로토타입에 존재해야 한다는 것입니다.
 
하지만 이 방법은 이전과 달리 부모 생성자 함수를 한번도 호출하지 않으므로 인스턴스 맴버는 상속 받지 못한다는 단점을 가지고 있습니다.

 

자바스크립트 상속 4


4. 생성자 빌려쓰기를 통한 다중 상속


  1. var Inherit = (function(){
  2.    
  3.     function Parent1(name){
  4.         this.name = name;
  5.         return this;
  6.     }
  7.  
  8.     Parent1.prototype.getName = function(){
  9.         return this.name;
  10.     };
  11.  
  12.     function Parent2(title){
  13.         this.title = title;
  14.         return this;
  15.     }
  16.  
  17.     Parent2.prototype.getTitle = function(){
  18.         return this.title;
  19.     };
  20.  
  21.  
  22.     function Child(name, title){
  23.         Parent1.call(this, name);
  24.         Parent2.call(this, title);
  25.         return this;
  26.     };
  27.  
  28.     return new Child('name', 'title');
  29.    
  30. })();
  31.  
  32. alert(Inherit.name); // name
  33. alert(Inherit.title); // title


다중 상속 구조를 설명하면 아래와 같습니다.

1. Parent1 생성자 함수에 인스턴스 맴버 name 속성을 추가 합니다.
 
2. Parent1 생성자 함수에 프로토타입 맴버 getName 메서드를 추가 합니다.
 
3. Parent2 생성자 함수에 인스턴스 맴버 title 속성을 추가 합니다.
 
4. Parent2 생성자 함수에 프로토타입 맴버 getTitle 메서드를 추가 합니다.
 
5. Child 생성자 함수 내부에서 Function.prototype.call() 메서드를 활용하여 Parent1 생성자
함수와 Parent2 생성자 함수의 인스턴스 맴버를 Child 생성자 함수의 맴버로 복사한다.
 
6. Child 생성자 함수의 프로토타입 맴버에 new Parent 객체를 추가 합니다.
 
7. new Child 객체를 반환 합니다.
 
8. 여기서 new Child 객체는 new Parent 객체의 인스턴스 맴버 모두(name)를 상속 받습니다.
(이전과 달리 프로토타입 맴버를 상속받지 않는 이유는 다중 상속 구조에서는 프로토타입
맴버를 추가 할 수 없기 떄문입니다.)
 
9. alert(Inherit.name);과 alert(Inherit.title);의 반환값이 각각 'name', 'title'이 나오는 이유는 5번 내용과 같이 Child 생성자 함수 내부에서 Function.prototype.call() 메서드를 활용하여 Parent1 생성자 함수와 Parent2 생성자 함수의 인스턴스 맴버를 Child 생성자 함수의 맴버로 복사하고, 그와 동시에 각가의 생성자 함수의 인자값('name', 'title') 또한 주었기 때문입니다.


자바스크립트 상속 3


3. 클래스 방식 상속(생성자 빌려쓰기) 1 - 2

 
  1. var Inherit = (function(){
  2.    
  3.     function Parent(name){
  4.         this.name = name || [1];
  5.         return this;
  6.     }
  7.  
  8.     Parent.prototype.getName = function(){
  9.         return this.name;
  10.     };
  11.  
  12.  
  13.     function Child(name){
  14.         // Function.prototype.call() 메서드를 활용하여 Parent 생성자 함수의 인스턴스 맴버를 Child 생성자 함수의 맴버로 복사한다.
  15.         Parent.call(this, name);
  16.         return this;
  17.     };
  18.  
  19.     Child.prototype = new Parent();
  20.  
  21.     return new Child([2]);
  22.  
  23. })();
  24.  
  25. alert(Inherit.getName()); // 2
  26.  


상속 구조를 설명하면 아래와 같습니다.

1. Parent 생성자 함수에 인스턴스 맴버 name 속성을 추가 합니다.
 
2. Parent 생성자 함수에 프로토타입 맴버 getName 메서드를 추가 합니다.
 
3. Child 생성자 함수 내부에서 Function.prototype.call() 메서드를 활용하여 Parent 생성자 함수의 인스턴스 맴버를 Child 생성자 함수의 맴버로 복사한다.
 
4. Child 생성자 함수의 프로토타입 맴버에 new Parent 객체를 추가 합니다.
 
5. new Child 객체를 반환 합니다.
 
6. 여기서 new Child 객체는 new Parent 객체의 맴버(인스턴스, 프로토타입)
모두(name, getName())를 상속 받습니다.
 
7. alert(Inherit.getName()); 반환값이 '1'아닌 '2'가 나오는 이유는 3번 내용과 같이 new Child 객체의 인스턴스 맴버는 Child 생성자 함수의 프로토타입을 통해 new Parent
객체의 인스턴스 맴버를 상속받지 않고 
Child 생성자 함수 내부에 Function.prototype.call() 메서드를 활용하여 Parent 생성자 함수의 인스턴스 맴버를 Child 생성자 함수의 맴버로 복사하고, 그와 동시에 생성자 함수의 인자값([2]) 또한 주었기 때문입니다.

 

자바스크립트 상속 2


2. 클래스 방식 상속 1 - 1

 
  1. var Inherit = (function(){
  2.    
  3.     function Parent(){
  4.         this.names = [1];
  5.         return this;
  6.     }
  7.  
  8.     Parent.prototype.getNames = function(){
  9.         return this.names;
  10.     };
  11.  
  12.  
  13.     function Child(){
  14.         return this;
  15.     };
  16.  
  17.     var p = new Parent();
  18.    
  19.     // 자바스크립에서 객체는 참조만 전달되기 때문에, 위와 같이 자식객체(new Parent)에서 names 맴버 속성을 수정하면 부모의 names 맴버 속성까지 수정된다.
  20.     p.names.push(2);
  21.     Child.prototype = p;
  22.  
  23.     return new Child();
  24.  
  25. })();
  26.  
  27. alert(Inherit.getNames()); // 1, 2


상속 구조를 설명하면 아래와 같습니다.

1. Parent 생성자 함수에 인스턴스 맴버 name 속성을 추가 합니다.
 
2. Parent 생성자 함수에 프로토타입 맴버 getName 메서드를 추가 합니다.
 
3. new Parent 객체의 names 맴버 속성을 수정한 후 Child 생성자 함수의 프로토타입 맴버에
new Parent 객체를 추가 합니다.
 
4. new Child 객체를 반환 합니다.
 
5. 여기서 new Child 객체는 new Parent 객체의 맴버(인스턴스, 프로토타입)
모두(name, getName())를 상속 받습니다.
 
6. alert(Inherit.getName()); 반환값이 1, 2가 나오는 이유는 5번 내용과 같이 수정된 new Parent
객체의 맴버를 모두 상속 받았기 때문입니다.


자바스크립트 상속 1


1. 클래스 방식 상속 1


  1. var Inherit = (function(){
  2.    
  3.     function Parent(){
  4.         this.name = 'parent';
  5.         return this;
  6.     }
  7.  
  8.     Parent.prototype.getName = function(){
  9.         return this.name;
  10.     };
  11.  
  12.  
  13.     function Child(){
  14.         return this;
  15.     };
  16.  
  17.    
  18.     Child.prototype = new Parent();
  19.  
  20.     return new Child();
  21.  
  22.  
  23. })();
  24.  
  25.  
  26. alert(Inherit.getName()); // parent
  27.  
 

위 코드가 가장 널리 쓰이며, 가장 기본적인 상속 방법 입니다.


상속 구조를 설명하면 아래와 같습니다.

1. Parent 생성자 함수에 인스턴스 맴버 name 속성을 추가 합니다.
 
2. Parent 생성자 함수에 프로토타입 맴버 getName 메서드를 추가 합니다.
 
3. Child 생성자 함수의 프로토타입 맴버에 new Parent 객체를 추가 합니다.
 
4. new Child 객체를 반환 합니다.
 
5. 여기서 new Child 객체는 new Parent 객체의 맴버그룹(인스턴스, 프로토타입)
모두(name, getName())를 상속 받습니다.

6. alert(Inherit.getName()); 반환값이 Parent가 나오는 이유는 5번 내용과 같이 new Parent
객체의 맴버를 모두 상속 받았기 때문입니다.

또한, 상속 과정을 거친 프로토타입은 아래처럼 서로 연결 됩니다.

--> (_proto_ 속성이 가리키는 방향)

new Child --> (Child.prototype : Object.prototype) --> new Parent (member: name) --> (Parent.prototype (member: getName()) : Object.prototype)



 

자바스크립트 method() 함수


이전 프스트 내용 중 모듈패턴1 의 내용을 다시금 상기시켜 보도록 하겠습니다.


자바스크립트에서는 생성자 함수를 통해 인스턴스 생성시 크게 2가지 형태의 맴버 그룹을
가질 수 있다고 말씀드렸습니다.


즉, 인스턴스 맴버그룹과 프로토타입 맴버그룹이 그것입니다.

두 가지 방식의 큰 차이점은 아래와 같습니다.

1. 인스턴스 맴버

- 각 인스턴스 생성시 생성자 함수의 this에 맴버를 추가하게 됩니다. 이는 각 인스턴스마다 맴버가 생성된다는 말과 같으며, 그만큼 메모리 관리에는 비효율적이라는 말과도 같습니다.


2. 프로토타입 맴버

- 인스턴스 맴버와는 달리 생성자함수 객체 속성인 prototype에 추가되며, 생성 주기 또한 각 인스턴스가 아닌 함수 생성시 한번만 실행되기 때문에, 재 사용 가능한 메서드들은
인스턴스 맴버가 아닌 프로토타입 맴버에 추가하여 사용하는것이 메모리 관리에 효율적입니다.


그러나 이런 자바스크립트만의 개발 방식이 기존 객체 지향 언어와는 개발자간에 여러 혼란을 주는것도 사실입니다.

이번 포스트에는 이런 혼란을 줄이기 위한 방법으로 더글라스 크록포드가 고안한 method 함수를 살펴 보겠습니다.

  1. // method 함수 추가
  2. (function(){
  3.     if (typeof Function.prototype.method !== 'function'){
  4.         Function.prototype.method = function(n, fn){
  5.  
  6.             if (typeof n !== 'string' || n.length === 0) return false;
  7.             if (typeof fn !== 'function') return false;
  8.            
  9.             this.prototype[n] = fn;
  10.  
  11.             return this;
  12.         }
  13.     };
  14. })();
  15.  
  16.  
  17. var a = function(id, name)
  18. {
  19.     this.id = id;
  20.     this.name = name;
  21. }
  22. .method('getId', function(){ return this.id; })
  23. .method('getName', function(){ return this.name; });
  24.  
  25. alert(new a('yanione1', 'name1').getId()); // yanione1
  26. alert(new a('yanione2', 'name2').getName()); // name2
  27.  
  28.  
  29.  
  30. var train = (function(){
  31.    
  32.     var init = function(name){
  33.         this.name = name;
  34.  
  35.     }.method('test1', function(){
  36.         return this.name;
  37.     });
  38.  
  39.     return init;
  40.    
  41. })();
  42.  
  43. var o = new train('name1');
  44. alert(o.test1()); // name1


단 여기서 이상한 점이 하나 있다면, 함수 선언부 코드 작성시 함수 리터널(var a = function(id, name)) 방식을 써야 생성시 에러가 나지 않는다는 것입니다.

분명 function a()와 var a = function() 모두 전역변수이며, 둘다 Function.prototype에 추가된 method 함수의 호출 까지는 에러가 나지 않지만 생성시 문법 오류가 때문입니다.

이 문제의 답에 대해서는 좀 더 알아본 후 포스트 내용에 추가 하도록 하겠습니다.
prev 1 ··· 6 7 8 9 10 11 12 next