원본 본문으로 이동하기

Javascript class

박용서 - 이 문서는 ECMAScript 6 추가 기능을 서술하고 있습니다. 모질라 문서 - 모질라 문서 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/class 참고사항 - ES 6 추가기능 : https://gs.saro.me/#!m=elec&jn=728 - 제네레이터 펑션 : https://gs.saro.me/#!m=elec&jn=726 일반적인 클래스와 상속 // class 이름 class Saro { // 생성자 constructor() { console.log('사로 생성자'); // 프로토타입 생성자함수 처럼 동적 this 로 사용. this.host = 'saro.me'; } // === 함수 / 함수 제네레이터와 / 프로퍼티 // === 이 3가지는 ES 6에서 굳이 클래스가 아니더라도 이렇게 표현할 수 있는 식이 추가됨. // === 위 참고사항의 : ES 6 추가기능 참고. // 제네레이터 펑션 : 여기서 다루지 않음 : 위 참고사항 참고 * genFunc() { /* ... */ } // get set 프로퍼티 : 여기서는 사용만함, 설명은 위 참고사항. get propertyValue() { return '호스트 : ' + this.host; } set propertyValue(host) { console.log('호스트는 바꿀수 없습니다.'); } // 함수 표현 getHost() { return this.host; } // 아래에서 상속받았을때 실험. getThis() { return this; } // 스테틱 함수의 경우 이렇게 사용한다. static staticFunction() { console.log('스테틱 함수입니다.'); } out() { console.log('사로 : ' + this.host); } }; // class 이름 extends 상속 : 많은 언어들의 상속과 같은 문법. class Garisani extends Saro { // 생성자 constructor() { // 생성자의 super 는 this 가 불리기 전에 해야한다. super(); console.log('가리사니 생성자'); this.host = 'gs.saro.me'; } // out 오버라이드 // param을 쓴 이유는 인자의 길이가 동적인 자바스크립트엔 // 오버로딩이 없다는 것을 설명하기 위함. out(param) { console.log('가리사니 : ' + this.host); console.log('상위 메서드를 불러볼까?'); // 일반적으로도 수퍼를 사용할 수 있다. super.out(); } }; console.log('Saro 생성준비'); var saro = new Saro(); console.log('Garisani생성준비'); // super 가 불려서 saro의 생성자가 작동한 것을 볼 수 있다. var gs = new Garisani(); console.log('모두 생성 완료'); // 출력 saro.out(); // gs.out 생성을 보면 자스엔 오버로딩이 없다는걸 보여주기위함. // 여기서는 파라미터를 쓰지않았지만 자스에선 파라미터가 arguments 개념이다. gs.out(); // 당연하지만 자바스크립트 상속은 스테틱도 상속한다. Garisani .staticFunction(); console.log('각 클래스의 이름 : 덮어쓰기를 할 수 없다.'); console.log(Saro.name); console.log(Garisani.name); console.log('프로퍼티 기능'); console.log(saro.propertyValue); console.log(gs.propertyValue); gs.propertyValue = "123"; // 입력불가 console.log(gs.propertyValue); console.log('this 를 리턴하는 함수를 상속 받으면 this 도 자동치환된다.'); gs.getThis().out(); 실행결과 뭔가 이상한 점들을 발견하지 않았는가? 부모객체와 맴버변수를 공유한다. - 보통 언어에선 부모와 맴버변수를 공유하지 않는다. - 잘 생각해보면 자바스크립트는 var 가 만능자료형이다. 맴버변수를 공유하다보니 낯선 결과가 보인다. - gs.out(); 실행부분을 보자 super.out(); 이 공유된 맴버번수 host를.. 부르는 특이함을 볼 수 있다... - 마찬가지로 get set 프로퍼티도 공유된 결과를 보인다. 오버라이딩은 되지만 오버로딩은 되지 않는다. - 자스에선 파라미터가 arguments 개념이다. - 즉, 파라미터가 달라져도 함수 이름으로만 부르며, 이 특성은 클래스에서도 달라지지 않는다. 접근자 설정이 없다. - 위 예제를 보면 클래스가 아닌 프로토타입의 확장처럼 느껴진다. - 추가 : 어떤 분께서 언어에 따라 클래스에 접근자가 기능이 없는 경우도 있다고한다. - 자스의 특징이 아님. 그렇다면 프로토타입 처럼 함수만 호출하면 따로 바인딩을 해줘야하나? - 바로 위 설명처럼 자바스크립트는 함수나 변수가, 다 같은 변수특성을 갖는다. // gs.saro.me console.log(gs.getHost()); var isMethod = gs.getHost; // 오류발생 : 그냥 프로토타입처럼 함수만 떨어져나왔다.. console.log(isMethod()); 그렇다.. 프로토타입과 동일 특성을 갖는다.. var temp; // 성공 - gs.saro.me temp = gs.getHost console.log(temp.bind(gs)()); // 성공 - saro.me temp = gs.getHost console.log(temp.bind(saro)()); // 동적으로 temp = gs.getHost console.log(temp.bind({ host : '동적값을 넣어보았다.' })()); saro 를 넣어도 성공한다.. 메서드라기보단 함수이다. 즉, 함수를 인자로 전달할대는 바인드 방식을 그대로 이용해야한다. 그럼 동적 프로토타입도 그대로 작동할까? Saro.prototype.out = function() { console.log('사로 클래스의 out을 프로토타입으로 덮어버림'); }; // 출력 saro.out(); gs.out(); 결과 사로 클래스의 out을 프로토타입으로 덮어버림 가리사니 : gs.saro.me 상위 메서드를 불러볼까? 사로 클래스의 out을 프로토타입으로 덮어버림 충격과 공포.... - 선언된 클래스의 함수(이제 메서드라고 부르긴...)도 프로토타입을 통해서 동적으로 덮을 수 있다. 분석 - 프로토타입을 기반으로 만들어진 클래스 유사한 것 같다. - 상속을 받고 super 로 상위 클래스에 접근 할 수 있다는 점이 프로토타입과의 다른 특징. 익명 클래스, 지역 클래스 생성방법 윗 부분에 있어야할 거같지만, 혼란스러움을 피하기 위해 여기에 작성되었다. var namespace = {}; // 이런식으로 변수 내부에 클래스를 만들 수 있다. // 이때보면 class의 이름이 생략된 것을 볼 수 있다. // 이렇게 이름이 생략된 클래스를 익명 클래스 라고한다. namespace.ClassA = class { } // 똑같이 변수에 넣지만 이번엔 이름이 있는 클래스를 만들어보았다. namespace.ClassB = class ClassNameIsB { } // 그렇다면 클래스 이름은? // 좀전에 만든 클래스의 이름들과 같이보자. console.log(Saro.name); // "Saro" console.log(Garisani.name); // "Garisani" console.log(namespace.ClassA.name); // "" console.log(namespace.ClassB.name); // "ClassNameIsB" - 자바스크립트