본문 바로가기

Learning/Javascript

JavaScript 객체 지향 프로그래밍 강좌 정독 완료

내가 본 강좌 

opentutorials.org/module/4047

 

JavaScript 객체 지향 프로그래밍

수업소개 JavaScript의 객체의 특성을 깊게 살펴보는 수업입니다. 이 수업에서는 아래와 같은 내용을 다루고 있습니다.  prototype __proto__ 생성자 함수와 new class 상속 수업대상 클라우드 컴퓨팅에 관

opentutorials.org

상당히 내 머리를 정리해 주는 강좌였다

역시 기본은 중요한 것

egoing 강의자 분에게 감사드리며(따로 로그인해서 댓글은 안 달았습니다.. ㅈㅅ)

 

아래로는 강좌를 따라한 코드들이다.

시간 날 때마다 한 번씩 계속 봐야 할 것 같다.

git에도 강좌를 보면서 작성한 내용을 올렸다

github.com/lean-net/study-javascript/tree/main/egoing

 

lean-net/study-javascript

javascript 공부. Contribute to lean-net/study-javascript development by creating an account on GitHub.

github.com

codesandbox

codesandbox.io/s/adoring-galileo-zqbfm

 

adoring-galileo-zqbfm - CodeSandbox

The online code editor tailored for web applications

codesandbox.io

 

강좌에서는 변수 선언 시에 var을 사용했는데

내 소스는 어느 순간부터 let를 사용하였다

별 차이가 없긴 하지만 변수 선언 위치에 따라서 var보다는

let이 확실하게 구분이 있는 부분 때문에 let을 사용하려고 한다

물론 구분이 없기 때문에 var을 사용하는 경우도 있겠지만...

 

1.hello.js
//콘솔창에 글나오게 할때
console.log("hello.js");
2.object.js
//객체의 기본적인 사용법
//객체는 이름이 있는 정보를(함수나 변수 등) 정리정돈 하는 도구
//배열 var를 써서 선언을 했지만 let으로 사용하는 버릇을 들이기
//배열은 대괄호 사용 안에 배열의 원소값을 넣음
var memberArray = ['a','b','c'];
//배열을 호출할때 배열의 시작은 0으로 시작함
//보통 vb와 db등 count는 1로 시작 실무에서 초짜일때 이부분 실수 많이 함
console.log("memberArray[1] : ",memberArray[1]);

//object의 선언은 중괄호를 사용
var memberObject = {
    manager:'a',
    developer:'graphittie',
    designer:'leezhce'
}
//객체에 저장된 원소의 값의 UPDATA(변경)
memberObject.designer = 'leezxhe';
//객체의 원소를 읽을때 .이나 대괄호[]를 사용하여 읽을 수 있다.
console.log('memberObject.designer : ', memberObject.designer);

//객체의 원소를 DELETE(삭제)
delete memberObject.designer;

//javacript에서 특수문자를 문자열로 표연할때는 \를 붙이면 된다.
console.log('memberObject[\'designer\'] : ', memberObject['designer']);


2.object.loop.js
//객체과 반복문
var memberArray = ['egoing','graphittie','leezche'];
//콘솔 로그를 남길때 그룹으로 지정 해서 관리 시작
console.group('array loop');

var i = 0;
//while 반복문
while(i < memberArray.length){
    console.log(i,memberArray[i]);
    i = i + 1;
}
//그룹 지정 끝
console.groupEnd('array loop');


var memberObject = {
    manager:'egoing',
    developer:'graphittie',
    designer:'leezche'
}

console.group('object loop');
//for 반복문
for(var name in memberObject){
    console.log(name, memberObject[name]);
}

console.groupEnd('object loop');
3.built-in.js
//수학 Math.PI 파이값 random 렌덤값 floor 나머지 버림
//이미 수학 날짜 문자 등 많은 객체를 만들었음
console.log('Math.PI : ',Math.PI);
//일반적으로 함수 function으로 말하지만 객체 안에 있는 function은 Method라고 말함
console.log('Math.random() : ',Math.random()); //random은 Method
console.log('Math.floor(4.3) : ',Math.floor(4.3));


let MyMath = {
    PI:Math.PI,
    random: function(){
        return Math.random();
    },
    floor:function(vl){
        return Math.floor(vl);
    }
}

console.log("MyMath.PI : ",MyMath.PI);
console.log("MyMath.random() : ",MyMath.random());
console.log("MyMath.floor(3.5) : ",MyMath.floor(3.5));

//위의 객체로 만든 부분을 객체로 만들지 않고 각자 만들기
//접두사를 써서 변수 이름 충돌 피하기
let MyMath_PI = Math.PI;

function MyMath_random(){
    return Math.random();
}

function MyMath_floor(vl){
    return Math.floor(vl);
}
4.this.js
//this는 method가 자신이 속해있는 객체를 가르키는 특수한 키워드

// let kim={
//     name:'kim',
//     age:'40',
//     first:10,
//     second:20,
//     sum:function(f,s){
//         return f+s;
//     }
// }

// console.log(kim.sum(kim.first,kim.second));

let kim={
    name:'kim',
    age:'40',
    first:10,
    second:20,
    sum:function(){
        //여기서 this는 kim이다. this.first는 kim.first
        return this.first+this.second;
    }
}

console.log(kim.sum());
5.object.factory.js

// let kim={
//     name:'kim',
//     age:'40',
//     first:10,
//     second:20,
//     sum:function(){
//         return this.first+this.second;
//     }
// }

// let lee={
//     name:'lee',
//     age:'23',
//     first:20,
//     second:30,
//     sum:function(){
//         return this.first+this.second;
//     }
// }

// console.log('lee.sum() : ', lee.sum());
// console.log('kim.sum() : ', kim.sum());


function Person(name,age,first){
    this.name = name,
    this.age =age,
    this.first=first,
    this.second=10,
    this.third=10,
    this.sum=function(){
        return this.first+this.second+this.third;
    }
}


//함수에 new가 붙으면 생성자가 된다 constructor
//constructor function을 만들면 여러 작업 없이 간단하게 지정 가능
//주소록 같은 그러고 보면 DB에서 이미 필드값이 정해져 있는 거에 하나의 행을 채우는 행위와 같아보임
let kim= new Person('kim','40',10);

let lee= new Person('lee','32',30);

console.log(kim.sum());

console.log(lee.sum());
6.prototype.js


//prototype은 함수가 선언될 때, 자동으로 선언되는 속성 객체로, 그 함수가 생성자로 이용되어 
//만들어진 모든 객체는 그 함수의 prototype을 참조한다. 이를 통해 함수가 생성자로 활용될 
//때마다 반복적으로 선언문이 실행되지는 않지만 그때 생성된 객체에서 공통적으로 활용 
//가능한 속성을 선언할 수 있다
function Person(name,age,first){
    this.name = name,
    this.age =age,
    this.first=first,
    this.second=10
}
//prototype 원형 객체에 메소드나 원소를 추가할때 사용
//sum이 안에 있을 경우 Person이 생성될때 마다 sum이 생성이 되어 메모리 낭비가 심해 지고
//sum을 수정 할경우 생성된 Person을 일일이 수정을 해야 하는 번거로움이 있음

Person.prototype.sum = function(){
    return 'prototype : ' + (this.first+this.second+this.third);
}
Person.prototype.third = 10;

let kim= new Person('kim','40',10);
//생성된 객체의 sum을 수정하는 경우
kim.sum  = function(){
    return 'this : ' + (this.first+this.second+this.third);
}
let lee= new Person('lee','32',30);
console.log(kim.sum());
console.log(lee.sum());
 
7.class.js

class Person{
    //constructor 객체가 생성될때 먼저 시작하는 함수
    constructor(name,age,first){
        this.name=name;
        this.age = age;
        this.first = first;
    }
    sum(){
        return (this.first);
    }
}
//class도 prototype을 사용하여 Method를 추가 가능
//extends 확장한다 즉 PersonPlus는 Person을 상속하고 추가 부분을 추가한 class이다. 
// class PersonPlus extends Person{
//     avg(){
//         return (this.first+this.second)/2;
//     }
// }

class PersonPlus extends Person{
    constructor(name,age,first,second){
        //super() 상속받은 부모 클레스의 생성자를 가져온다.
        super(name,age,first)
        this.second=second;
    }
    sum(){
        //super.xxx 상속받는 부모 클레스의 메소드임 메소드 뒤에 () 붙어야지 return값을 가져옴
        
        return super.sum()+this.second;
    }
    avg(){
        return (this.first+this.second)/2;
    }
}

let kim= new PersonPlus('kim',40,10,20);
console.log(kim.sum());
console.log(kim.avg());

8.prototype.inheritance.js

let superObj = {superVal:'super'}
let subObj = {subVal:'sub'}
//__proto__ 정규문법은 아님 하지만 다씀 prototypelink
subObj.__proto__ =  superObj;

console.log('subObj.subVal => ',subObj.subVal);
console.log('subObj.superVal => ',subObj.superVal);

subObj.superVal = 'chg';
//디버깅모드 중단점 같음 크롬에서 확인 가능 궁금한 오브젝트 이름을 왓쳐로 검색 가능
//debugger;
console.log('subObj.superVal => ',subObj.superVal);
console.log('superObj.superVal => ',superObj.superVal);

let superObj1 = {superVal:'super'}
//__proto__ 와 같은 의미 아래가 더 정규방식이라고 함
let subObj1 = Object.create(superObj1);

console.log('superObj1.superVal => ',superObj1.superVal);
console.log('subObj1.superVal => ',subObj1.superVal);

let kim = {
    name:'kim',
    first:10,second:20,
    sum: function(){
        return this.first + this.second;
    }
}

let lee = Object.create(kim);
lee.name = 'Lee';
lee.first = 20;
lee.firsts = 30;
lee.second = 50;
lee.avg = function(){
            return (this.firsts+this.second)/2;
        }
// let lee = {
//     name:'Lee',
//     first:20,second:50,
//     avg:function(){
//         return (this.first+this.second)/2;
//     }
// }

lee.__proto__ = kim;

console.log('lee.avg => ',lee.avg());
console.log('lee.sum => ',lee.sum());
9.object.function.js

let kim = {name:'kim',first:10,second:20}
let lee = {name:'lee',first:10,second:10}

// lee.__proto__ = kim;

function sum(prefix){
    return prefix +(this.first + this.second);
}

//sum(); = sum.call();
//call의 첫번째 인자값은 this가 될 객체, 두번째 인자는 함수의 파라미터에 대입될 값
//call과 비슷한 기능인 apply가 있다
console.log('sum.call(kim) : ', sum.call(kim, '=> '));
console.log('sum.call(lee) : ', sum.call(lee, ' =: '));

//bind
let kimSum = sum.bind(kim,' ): ');
console.log('kimSum : ' , kimSum());

//call은 실행할때 함수의 this를 원하는 객체로 바꾸는것
//bind는 실행하는 함수의 this를 원하는 객체로 고정을 시키는 새로운 함수를 생성한다.
10.prototypeVS__proto__.js

//function Person (){};
//let Person = new function();
//둘다 동일

//javascript의 함수는 객체이기 때문에 property(속성)을 가질수 있다.

function Person(name,first,second){
    this.name = name;
    this.first = first;
    this.second = second;
}

//1. Person이라는 생성자 함수 객체가 생성
// Person
// --------------------
//(property) - prototype (Person의 prototype을 가르키는 property)

//1-1. Person의 prototype 객체가 생성 (Person의 property)
// Person's prototype
// ---------------------
//(property) - constructor (Person을 가르키는 property)

Person.prototype.sum = function(){};

//1-2. Person의 prototype 객체가 생성 (Person의 property)
// Person's prototype
// ---------------------
//(property) - constructor (Person을 가르키는 property)
//- sum

let kim = new Person('kim',10,20);

//2-1. Person이라는 생성자 함수를 사용해 kim이라는 객체를 생성
// kim
// -----------------
// - __proto__ (Person의 prototype을 가르키는 property)
// - name
// - first
// - second

console.log(kim.sum());
//kim 객체의 property에서 sum() Method를 찾지만 없으면 __proto__가 가르치는 Person's prototype 객체에 sum()이라는 Method를 찾는다.
//또 없으면 Person's prototype의 __proto__가 가르치는 객체에서 sum()이라는 Method를 찾게 된다.



11.constructor.inheritance.js

//7.class.js와 비교

function Person(name,first,second){
    this.name = name;
    this.first = first;
    this.second = second;
}

Person.prototype.sum = function(){
    return this.first + this.second;
}

function PersonPlus(name,first,second,third){
    Person.call(this,name,first,second);
    this.third = third;
}

//PersonPlus.prototype.__proto__ = Person.prototype;
//위와 아래 두개는 같은 의미
PersonPlus.prototype = Object.create(Person.prototype)
//PersonPlus.prototype.constructor는 생성자를 가르킴
PersonPlus.prototype.constructor = PersonPlus;

PersonPlus.prototype.avg = function (){
    return (this.first + this.second + this.third)/3;
}

let kim= new PersonPlus('kim',40,10,20);

console.log(kim.sum());
console.log(kim.avg());
console.log(kim.constructor)