인사이드 자바스크립트를 공부하며 정리하는 포스팅입니다.
1.클래스, 생성자, 메서드
일반적으로 C++, Java와 같은 언어에서는 class라는 키워드를 제공하여 프로그래머가 클래스를 만들 수 있다.
그리고 클래스와 같은 이름의 메서드로 생성자를 구현한다. 그러나 자바스크립트에는 이러한 개념이 없다.(ES5에서는)
자바스크립트에서는 함수객체로 클래스, 생성자, 메서드도 구현 가능하다.
var Person = function(arg){ this.name = arg; }; Person.prototype.getName = function(){ return this.name; } Person.prototype.setName = function(name){ this.name = name; } var me = new Person("song"); console.log(me.getName());
2.상속
자바스크립트는 클래스를 기반으로 하는 전통적인 상속을 지원하지는 않는다.(ES5기준) 하지만 자바스크립트 특성 중 객체 프로토타입 체인을 이용하여 상속을 구현할 수 있다.
1) 클래스 개념 없이 객체의 프로토타입으로 상속 구현하기.
아래 예제는 더글라스 크락포드가 자바스크립트 객체를 상속하는 방법으로 소개한 코드이다.
var create_object = function(o){ function F() {} F.prototype = o; return new F(); };
생성된 F객체는 object o에 프로토타입 링크가 연결되어 있고,
또, 이 object o는 Object prototype에 프로토타입 링크가 연결되어 있다.
그리고 프로토타입으로 상속을 구현하기에 중심이되는 또 다른 메서드가 있다.
바로 extend() 메서드이다. 자바스크립트에서는 범용적으로 extend() 메서드로 자신이 원하는 객체 혹은 함수를 추가시킨다.
다음 코드는 jQuery 1.0의 extend 함수이다.
function extend(obj, prop){ if(!prop){prop = obj; obj = this;} for(var i in prop) obj[i] = prop[i]; return obj; }
위와 같은 extend() 함수의 약점은 얕은 복사를 하고 있다는 것이다. 프로퍼티 중 객체가 있는 경우 깊은 복사를 하는 것이 일반적이다.
create_object(), extend() 메서드를 이용하여 상속을 하는 예제를 구현해 보자.
//클래스 개념 없이 프로토타입 특성으로만 상속 구현하기 //더글라스 크락포드가 자바스크립트 객체를 상속하는 방법으로 소개한 코드. var create_object = function(o){ function F() {} F.prototype = o; return new F(); }; // _proto_ _proto_ //F ------> object o -------> Object.prototype var person = { name : "song", getName : function(){ return this.name; }, setName : function(arg){ this.name = arg; } }; var student = create_object(person); student.setName("ssong"); console.log(student.getName()); //위와 같이 부모 객체의 메서드를 그대로 상속받아서 사용할 수 있고, 자신의 메서드를 재정의 혹은 추가로 구현할 수 있다. //이때, 자바스크립트에서는 범용적으로 extend()라는 이름의 함수로 자산이 원하는 객체 혹은 메서드를 추가한다. function extend(obj, prop){ if(!prop){prop = obj; obj = this;} for(var i in prop) obj[i] = prop[i]; return obj; } var studentAdded = { setAge : function(age){ this.age = age; }, getAge : function(){ return this.age; } }; extend(student, studentAdded); student.setAge(25); console.log(student.getAge()); //한 단계 더 상속을 구현해보도록 하겠다. //student를 상속받은 HiSchoolStudent를 구현하겠다. var hiSchoolStudent = create_object(student); var hiSchoolStudentAdded = { grade : 3, setGrade : function(grade){ this.grade = grade; }, getGrade : function(){ return this.grade; } }; extend(hiSchoolStudent, hiSchoolStudentAdded); console.log(hiSchoolStudent.getName()); console.log(hiSchoolStudent.getAge()); console.log(hiSchoolStudent.getGrade());
2) 클래스역할을 하는 함수로 상속하기.
아래 예제는 일반적인 상속 예제이다.
핵심이 되는 부분은 Student.prototype에 부모가 될 Person의 인스턴스를 넣어주고, 생성자를 다시 지정해주는 것이다.
이렇게 함으로써, Student의 객체는 Person 객체의 함수와 메서드를 사용할 수 있게 프로토타입 링크가 형성된다.
주의할 점은 자동으로 부모 객체의 생성자가 호출되지는 않으므로 자식 생성자에서 부모 생성자를 호출해주어야 한다.
Person.call(this, name); 부분이 부모 생성자를 호출해 주는 부분이다.
부모 생성자에 생성될 객체를 this로 넘긴다.
//클래스역할을 하는 함수로 상속하기 var Person = function(name){ this.name = name; }; Person.prototype.setName = function(name){ this.name = name; }; Person.prototype.getName = function(){ return this.name; }; var Student = function(name, _calss){ //부모클래스 생성자 호출 Person.call(this, name); this.class = _calss; }; Student.prototype = new Person(); Student.prototype.constructor = Student; Student.prototype.getClass = function(){ return this.class; }; Student.prototype.setClass = function(_calss){ this.class = _calss; }; var song = new Student("song", 3); console.log(song.getName()); console.log(song.getClass()); console.log(song instanceof Person); // true console.log(song instanceof Student); // true
3.캡슐화
자바스크립트의 강력한 특성 중 하나인 클로저를 활용하여 캡슐화를 할 수 있다.
1) 기본 예제
아래 예제는 public 메서드가 클로저 역할을하고, private 멤버인 name에 접근한다.
자바스크립트에서 할 수 있는 기본적인 정보은닉 방법이다.
*모듈 패턴
주의할 점은 private 멤버가 객체나 배열인 경우 사용자가 get~~()함수를 통해 받은 값을 손쉽게 수정할 수 있다. 때문에 깊은 복사를 통해서 새로은 객체나 배열을 리턴해주어야 한다.
var Person = function(arg){ var name = arg ? arg: "song"; return { getName: function(){ return name; }, setName: function(arg){ name = arg; } }; } var song = Person(); // or var song = new Person(); console.log(song.getName());
위 예제는 객체를 리턴하는데, 이 객체는 Person 함수 객체의 프로토타입에는 접근할 수 없다.
때문에 Person을 부모로 하는 프로토타입을 이용한 상속을 구현하기에는 용이하지 않다. 때문에 이를 보완하기 위해 함수를 반환한다.
2) 캡슐화를 적용한 상속가능 함수.
var Person = function(arg){ var name = arg ? arg: "song"; var Person = function(){} Person.prototype = { getName: function(){ return name; }, setName: function(arg){ name = arg; } }; return Person; }(); var song = new Person(); console.log(song.getName());
'Web Front > Javascript' 카테고리의 다른 글
[InsideJavascript] 11. 함수형 프로그래밍 (0) | 2018.05.21 |
---|---|
위도, 경도 to Pt (0) | 2018.05.03 |
[InsideJavascript] 9. 클로저 (0) | 2018.04.27 |
[InsideJavascript] 8. 스코프 체인 (0) | 2018.04.27 |
[InsideJavascript] 7. 실행 컨텍스트 (0) | 2018.04.27 |