-
[JS] 객체 지향 - 생성자와 new, 전역객체, this, 상속, prototype생활코딩/ 2020. 9. 5. 00:25
[강의 출처] opentutorials.org/course/743/6584
객체 지향 프로그래밍(Object Oriented Programming)
-프로젝트가 확장되면서 기존의 절차적인 방법으로 정리하기 어려워질 때, 기능별로 로직을 구분해서 정리하는 방식 중 하나
-해당 문법과 설계방식(문제의 복잡성을 적절히 단순화하여 설계하는 추상화(abstract)와 그룹핑, 캡슐화 등)을 아우르는 개념
-JS는 Prototype-based Programming에 속함
생성자(constructor)와 new
-일반적으로 객체를 만드는 방법은 아래와 같다.
var person = { 'name' = 'a'; 'introduce' = function(){ return 'My name is ' + this.name; } } document.write(person.introduce());
-만약 person이라는 형식으로 객체를 여러 개 만들고 싶다면 생성자를 이용한다.
-생성자(constructor)는 객체를 만드는 함수다. 자바스크립트에는 클래스가 없기 때문에 생성자는 객체와 독립적이다.
function Person(); // 함수를 정의 var p = new Person(); // 새로운 객체가 생성된다 p.name = 'a'; p.introduce = function(){ return 'My name is ' + this.name; }
-아래처럼 생성자로 쓰일 함수를 정의할 때, 필요한 로직(메소드와 프로퍼티 등)을 정의해두면 편리하게 객체를 생성할 수 있다.
이런 작업을 초기화(initialize)라고 부른다.
function Person(name){ // 생성자로 쓰일 함수 정의 this.name = name; this.introduce = function(){ // 여기서 메소드를 정의해두면 return 'My name is ' + this.name; // 이후 선언되는 객체들에서 반복적으로 사용가능 } // 이런 초기 세팅을 '초기화'라고 부름 }; var p1 = new Person('a'); // 생성자 Person에서 프로퍼티를 'a'로 정의 var p2 = new Person('b'); document.write(p1.introduce() + "<br />"); document.write(p2.introduce() + "<br />");
전역객체(Global Object)
-자바스크립트의 모든 객체(전역변수 및 함수를 포함해서)는 window 객체의 프로퍼티다. [참고페이지]
-node.js에서는 전역객체를 global라고 부른다.
function func(){ console.log('Hello?'); }; func(); // 'Hello?' window.func(); // 'Hello?'
this
-함수 내에서 함수를 호출한 맥락(context)의 객체를 가리킨다. this를 통해 함수와 객체를 연결시킬 수 있다.
/* 별다른 맥락이 없는 경우, 전역객체인 window를 가리킨다 */ function func(){ if(window === this){ console.log("window === this") } } func(); // window === this
/* 객체에 소속된 메소드의 this는 그 객체를 가리킨다 */ var o = { func: function(){ if(o === this){ console.log("o === this"); } } } o.func(); // o === this
-this는 객체 생성이 끝나서 어떤 식별자에 담기기 이전에도(객체 생성 진행 중에도) 해당 객체에 접근이 가능하다.
/* 생성자 안에서 this는 생성될 객체를 가리킨다*/ var funcThis = null; // 다른 함수에서도 불러와야 하니까 일단 전역변수로 세팅 function Func(){ funcThis = this; // 여기에서 this의 값으로 funcThis 재할당 } var o1 = Func(); // new 없이 생성한 경우 if(funcThis === window){ // 함수 Func() 맥락에서 그 함수의 객체는 window가 됨 console.log('window'); // 'window' } var o2 = new Func(); // 생성자를 이용해 생성한 경우 if(funcThis === o2){ // 호출한 시점에서 비어있는 {} 객체가 만들어지고, 그 객체가 생성자 내의 this console.log('o2'); // 'o2' function Func(){ console.log(o); } var o = new Func(); // undefined // 이 경우 호출이 모두 끝나야 var o가 할당완료되고, this가 o가 되는데, // 생성 중간에 o를 호출한 것이므로 아직 정의되지 않았다고 출력된다.
-함수의 메소드 apply, call를 통해, 타 객체의 메소드를 적용 가능함
*리터럴(literal)의 개념
더보기new로 객체를 정의하지 않고 일반적인 방법으로 객체를 생성하는 경우 ~ 리터럴이라고 부른다
// 함수 리터럴(function literal) function sum(x,y){ return x+y; } // 객체 리터럴 var o = { } var p = { } // 배열 리터럴 var a = [1, 2, 3];
var o = {} var p = {} function func(){ switch(this){ case o: console.log('o'); break; case p: console.log('p'); break; case window: console.log('window'); break; } } func(); // 'window' func.apply(o); // 'o' func.apply(p); // 'p' /* apply가 사용된 맥락에 따라 window.func(), o.func(), p.func()처럼 해석됨 */
상속(inheritance)
-어떤 객체의 로직(메소드, 프로퍼티 등)을 prototype 객체를 통해 다른 객체에게 물려줄 수 있는 기능
-상속을 통해 기존 객체로부터 새로운 파생 객체를 만들 수 있음
function Person(name){ this.name = name; } Person.prototype.name = null; // 빌트인 메소드 prototype으로 프로퍼티 추가도 가능 Person.prototype.introduce = function(){ return 'My name is ' +this.name; } function Programmer(name){ this.name = name; } Programmer.prototype = new Person(); // 이렇게 해서 Person의 로직을 상속 받음 Programmer.prototype.coding = function(){ // 상속받은 부모 객체의 prototype을 복사 return "hello world!"; // coding()은 Programmer만 실행 가능한 메소드 } function Designer(name){ this.name = name; } Designer.prototype = new Person(); Designer.prototype.design = function(){ // Designer의 고유 메소드를 구현 return "beautiful!"; } var p1 = new Programmer('a'); console.log(p1.introduce()); // My name is a. Person의 메소드를 상속 받음 console.log(p1.coding()); // hello world! var p2 = new Designer('b'); console.log(p2.introduce()); // My name is b. Person의 메소드를 상속 받음 console.log(p2.design()); // beautiful! console.log(p2.coding()); // Designer 객체는 coding 프로퍼티가 없으므로 에러 /* Uncaught TypeError: p2.coding is not a function */
prototype
-프로토타입 객체의 프로퍼티들은 생성자를 통해서 객체가 생성될 때 그 객체로 전달된다.
-이렇게 프로토타입을 통해 프로퍼티들이 연결되는 형태를 'prototype chain'이라고 부른다.
function Ultra(){} Ultra.prototype.ultraProp = true; function Super(){} Super.prototype = new Ultra(); function Sub(){} Sub.prototype = new Super(); // 상속받고자하는 객체를 새로 생성해서 new() 형태로 전달해야함 // Super.prototype()형태로 전달할 경우, Sub 객체의 변경사항이 var o = new Sub(); // 부모인 Super 객체에도 영향을 줄 수 있기 때문 console.log(o.ultraProp); // true
'생활코딩 > ' 카테고리의 다른 글
[JS] 탬플릿 리터럴(`를 이용한 표현식) (0) 2020.09.09 [JS] 객체 지향 - 표준내장객체와 확장, 데이터 타입, 참조 (0) 2020.09.07 [JS] 함수 - 유효범위, 콜백, 클로저, arguments, 호출 (0) 2020.09.03 [JS] 개요 - 함수, 배열, 객체, 모듈, Reference 참조, 정규식 (0) 2020.09.01 [JS] 개요 - 숫자와 문자열, 변수, 비교연산자, 조건문, 반복문 (0) 2020.08.31