PracticeEveryday
JavaScript 에서의 객체지향 본문
객체지향 프로그래밍의 발전
JavaScript와 객체 지향
- 자바스크립트도 객체 지향의 패러다임이 가장 핫한 시기에 만들어진 언어이니 객체 지향의 영향을 받지 않을 수
없었습니다.
- 하지만 자바스크립트를 맨 처음 설계한 사람은 객체 지향 프로그래밍에 대한 회의적인 시각을 갖고 있었습니다.
- 그렇기에 당시 유행했던 객체지향의 개념은 그대로 가져오되 주류였언 Java와는 전혀 다른 방식으로 OOP를 풀어내게
됩니다.
Javascript 탄생비화
Javascript를 창시한 Brendan Eich는 언어를 개발할 당시 유행하던 객체지향에 한계를 느끼고 LISP, scheme 등
함수형 프로그래밍에 관심을 가지고 있었기에 함수형 프로그래밍의 형태로 언어를 만들고 싶어 했습니다.
하지만 Netscape의 그의 상사는 당시 개발자들이 제일 많이 쓰던 Java와 같은 문법으로 만들기 요구했기 때문에
결국 둘의 혼종의 형태로 세상에 나오게 되었습니다.
- JavaScript는 설계자의 철학도 그랬지만 웹 브라우저에서는 처음부터 복잡한 언어를 만들 생각이 없었습니다.
그저 아주 간단하고 작은 형태의 스크립트 언어면 될 거라고 생각했기 떄문입니다.
- 그래서 복잡한 class나 설계, 추상화나 다형성 등을 만들기를 원하지 않았습니다.
- 하지만 당시 가장 인기 있었던 Java 개발자들을 끌어들이고 싶었기에 Java 문법과 패러다임은 최대한 유지를 해보고자
노력하게 되었습니다.
- 그래서 class가 없는 함수형 언어를 기반으로 하지만 객체 지향 프로그래밍 맛을 느낄 수 있는 언어가 탄생하게
된 것입니다.
JavaScript의 설계자가 되어보자
- OOP, Class 문법은 너무 복잡해! 최대한 간단하게 만들되 객체지향 처럼 상속, 추상화, 다형성을 할 수 있으면
되지 않을까?
1. class가 없는데 객체는 어떻게 만들까?
- class 없이 바로 Object를 생성할 수 있게 하면 되겠다!. JS는 No Class 언어!
- 이렇다면 Java처럼 o.name, o.age 객체 문법을 쓸 수 있을 것이다!
var cat = {
name: "냥이",
age: 1
}
console.log(o.name)
console.log(o.age)
2. 타입이 없는데 객체가 가진 메소드는 어떻게 동작해야 될까?
- Java 문법과 유사하게 객체에 함수를 정의하면 this를 넘겨주면 되지 않을까?
var cat = {
name: "냥이",
age: 1
speak: function() { console.log("야옹~~", this.name, this.age) }
}
cat.speak()
3. 그럼 상속과 추상화, 다형성은?
- 상속이라는 것이 결국 이미 만들어진 값들을 받아서 쓰는 것인데 class 가 아니라 Object에서 받아오면 되지 않을까?
- 그래서 있으면 내 걸 쓰고 없으면 부모 값을 쓴다면 결과는 똑같을 거 같은데
=> 상속 받는 다는 것이 아니라 없으면 찾아간다는 식으로 연결을 해보면 어떨까?
var animal = {
name: "",
age: 0
sleep: function() { console.log("sleep... zzz", this.name) }
speak: function() { console.log("...", this.name) }
}
var cat = {
name: "냥이",
age: 1
speak: function() { console.log("야옹~~~", this.name, this.age) }
}
// 상속을 받는(척 하지만 prototype 연결)
car.__proto__ = animal
newObj.sleep()
// cat에는 sleep없으니 연결된 animal를 찾아가서 sleep을 호출.. 이걸로 마치 상속 해결!
newObj.speak()
// cat에 있는 속성이니 본인의 speak호출! 이걸로 다형성 해결!
4. 그래도 class와 new를 이용해서 객체를 생성하는 방식은 필요하지 않을까?
- 그래도 class는 넣지 않을 것! function으로 처리해보자
- prototype을 통해 이렇게 정리하면 class 없이도 객체 지향을 할 수 있을 것이다!
function Cat(name, age) {
this.name = name
this.age = age
}
Cat.prototype.speak = function() { console.log("야옹~~~", this.name, this.age) }
var cat = new Cat("냥이", 1)
cat.speak()
- 이렇게 class 없이 object에 prototype 체인을 연결하는 방식을 통해 객체 지향의 문법과 객체 지향의 삭속, 추상화,
다형성을 해결하게 되었습니다.
- 그리고 이러한 객체들을 바탕으로 Object, String, Number, Function, Array 등에도 객체 지향의 개념을 부여한 기본
라이브러리를 만들어서 class는 없지만 마치 객체지향의 언어를 사용하는 느낌으로 코드를 작성할 수 있는 언어가
탄생하게 되었습니다.
Class 없어 어떻게..
- 당시에는 class가 없이 프로그래밍을 한다는 것은 상상도 하기 힘들었습니다.
그렇기에 JavaScript가 출시 되었을 때 수준 낮은 언어로 폄하당했습니다..
- 결국 제작자의 의도와 관계없이 가장 많이 요구하던 문법적인 기능이 바로 class였으며 결국(?) ES6에 와서는 class가
정식 문법이 되었습니다.
- 하지만 ES6의 class는 Javascript 객체지향의 근간인 prototype 방식을 문법적으로 class처럼 보이게 만들어준 도구에
불과합니다
타입도 없고 interface도 없네요..
- 오리처럼 걷고 오리처럼 꽥꽥거리면 오리지..
// 타입이 뭣이 중한겨? 그냥 메소드를 가지고 있으면 실행하면 되지..
function test(duck) {
if (typeof duck.walk === "function") {
duck.walk()
}
if (typeof duck.quack === "function") {
duck.quack()
}
}
var duck1 = {...}
var duck2 = {...}
test(duck1)
test(duck2)
- 자바스크립트는 타임으로 인한 복잡성을 추구하지 않기 위해 객체의 타입을 따지지 않습니다.
- 같은 이름의 변수나 메소드를 가지고 있다면 같은 타입의 객체라고 할 수 있다.
이를 통해 복잡한 객체지향 프로그래밍의 설계를 복잡한 타입 정의와 상속을 통해 interface에 맞추지 않고
아주 간단하게 만들어 줄 수가 있었다.
함수가 1급 객체다!
- 논란이 많은 JavaScript 였지만 그럼에도 초기 설계중 가낭 칭찬받는 점은 함수가 1급 객체라는 것이었습니다.
- 함수를 값으로 넘길 수 있고 익명 함수와 클로저를 통해 값을 보관하고 전달할 수 있다는 개념을 통해서, 기존의
객체 지향에서 복잡하게 구현을 해야 했던 수많은 패턴들이 아주 간단하게 해결되었습니다.
- 함수가 값이 될 수 있다는 점은 추후 많으 객체 지향 언어에 새로운 영감을 주어, 지금은 객체 지향만 고집하지 않고
함수형과 객체지향을 적절히 섞어 쓰는 방식으로 발전하고 있습니다.
- 결국 객체 지향의 시각으로 보았을 때 모자라던 언어가 이제는 객체 지향의 패러다임에 영향을 주고 있는 언어가
되었습니다.
객체지향의 개념으로 데이터와 메소드를 통해 독립적인 작은 프로그램으로써 만들어 편리하게 재사용하는 장점을 취하되, 객체들의 결합이 높아져서 프로그램이 과도하게 복잡해지지 않도록 굳이 객체로 만들지 않아도 될 부분들은 함수형으로 만들어 활용하세요.
결국 간단하고 가독성 있고 덩치가 커져도 유지보수하기 좋으며 재사용이 편리한 코드를 만들어 내는 것이 Javascript를 잘하는 것입니다. Javascript는 객체지향과 함수형의 2가지 관점을 모두 가지고 있는 언어기에 이러한 밸런스를 잡는 것이 중요합니다. 물론 언제나 말은 쉽습니다. 실천이 어려운 것이죠.
자바스크립트에서 객체 지향을 하는 게 맞나요? | 요즘IT
이번 글에서는 객체지향 프로그래밍에 대해 이야기를 해보려고 합니다. 그리고 자바스크립트의 객체지향은 일반적인 객체지향 프로그래밍과는 어떻게 다른지 그리고 Javascript에서는 객체지향
yozm.wishket.com
'정리 > Question' 카테고리의 다른 글
ESlint (0) | 2022.06.15 |
---|---|
JavaScript 에서의 객체지향 (0) | 2022.06.14 |
JavaScript 에서의 객체지향 (0) | 2022.06.14 |
JavaScript 에서의 객체지향 (0) | 2022.06.14 |
@types (0) | 2022.06.04 |