상세 컨텐츠

본문 제목

시베리안 허숙희의 자바스크립트 비기닝 20 (prototype 프로토타입)

자바스크립트

by e7e 2023. 6. 16. 10:30

본문

도톰한 손에 아직 자스(크립트)가 낯설지 모르겠지만, 눈은 이미 많은 걸 보았고,

뇌는 꽤 다름을 인지, 자스에 대한 당근 큰 그림을 그리기 시작!, 어쩌면 꿈을 꿀지게 꿀지도 모른당!

곧 어느 정도 전체모습(개념)이  프레임화 되었을 것이당.

 

기어를 올리고, 가속 페달을 밟기 시작할 시점이당.(두려움은 기대와  스릴의 다른 표현!)

먼저 아래 코드와 실행 결과를 통해 코드를 이해하장(모두 보았던 내용이당!)

<!DOCTYPE html>
<meta charset="UTF-8">
<script>
// 나만의 배열 클래스 선언
const MyArray = function(){
    this.length = 0;               // 배열의 핵심 속성 length 추가(몇개?)

    this.push = function(pElem){   // 핵심 메소드 push구현
        this[this.length] = pElem; // JSON 배열식 표기법 활용(중요)
        this.length++;             // 추가했으니 갯수 증가
    }

    return this;          // 생략가능 암묵적 존재,난 명시적 표현 좋앙!
}

const arrObj1 = new MyArray();
for(let i=1; i<=3; i++){
    arrObj1.push(`메롱 ${i}`);
}
console.log("arrObj1:",arrObj1);
console.log("arrObj1:",arrObj1.length);


const arrObj2 = new MyArray();
for(let i=1; i<=5; i++){
    arrObj2.push(`메롱 ${i*5}`);
}
console.log("arrObj2:",arrObj2);
console.log("arrObj2 갯수:",arrObj2.length);
</script>

자암깐 여기서 생각해 보아야 할 문제가 있당!(개념적으로 중요)

MyArray의 인스탄스인 arrObj1과 arrObj2가 모두 각자의 push메소드를 가진당!(console.log확인)

length라는 속성은 push메소드에 의해 갯수가 변한 상태를 저장한당!

하지만 push메소드 자체는 그저 실행되는 기능일 뿐 자체적으로 어떤 상태도 저장하지 않는당!

무언가 낭비되고 있다는 느낌이 강하고 강하게 엄습한당.

 

억지 현실의 예를 들어보장 .착하지만 효율적이지 못한 사람들이 모여사는 어휴란 마을이 있당!

이 마을의 모든 주민은 각자 자신의 집에  최신  명품 다이슨 트랜스포머 포크레인을 가지고 있당.

너무 착한 나머지 빌려쓰기 미안해서당.(사실 나도 가지고 싶당)

연못을 만든다 치면, 연못이 원하는 결과물이고 포크레인은 작업 중간에 필요한 도구일뿐이다.

결론을 말하자면, 마을 동사무소에 1대 사두고( 고장 안나게 관리 잘해야 함), 필요한 사람이

필요할 때 가져다 쓰면, 각자 집 마당 공간(메모리)도 넓게 쓰고, 전체적으로 효율적이지 않을깡?

갑자기 누가 훅 들어온당. 마을 주민 모두가 중장비 사업자라면요?

 

그래서 자스에선 prototype(프로토타입)이란 걸 쓰는데, 해당 클래스 출신의 Instance들이 

메소드를 공유해서 쓸 수 있는 영역이라고 쉽게 쉽게 생각하면 된당!

메소드 아닌 속성도  저장할 수 있지만 의미없당!(왜 그런지 각자 생각해 보장!-> 절대 안 알려줌)

prototype관련 해서는 인터넷상의 너무 과한 설명들이 개발자들의 뇌를 좌절로 죽이려드니,

말려드지 말고, 미필적 고의 아니고 우발적인 양 스케줄에서 빼장!

 

실제 요즘은 가정에서 가끔 쓰는 공구들이나, 평상시에 자주 필요하지 않은 것들을,

해당 동주민이라면 동사무소에서 대여해서 쓸 수 있는데, 그따구로 받아들이장!

 

프로토타입(prototype)을 이용해서 MyArray만 다시 작성하면 아래와 같당.

// 나만의 배열 클래스 선언
const MyArray = function(){
    this.length = 0;               // 배열의 핵심 속성 length 추가(몇개?)
    return this;          // 생략가능 암묵적 존재,난 명시적 표현 좋앙!
}

// 프로토타입(prototype) 이용 메소드 선언
MyArray.prototype.push = function(pElem){   // 핵심 메소드 push구현
        this[this.length] = pElem; // JSON 배열식 표기법 활용(중요)
        this.length++;             // 추가했으니 갯수 증가
}

MyArray.prototype.reduce = function(pCallback,pInitVal) {  
        var accumulator = this[0];
        var startIndex = 1;
        if(pInitVal){
            accumulator = pInitVal;
            startIndex = 0;
        }
        for (let i = startIndex ; i < rslt.length; i++) {
            accumulator = pCallbe(accumulator, this[i], i)
        }
        return accumulator;
}

 

아래 코드는 조금 길긴 하지만, 배열의 자주 쓰는 메소드(이전엔 콜백사용하는 것은 하지 않았음)들의

내부적 기능을 간략히 구현해 본 것으로, 시간을 내어 꼬옥 흐름을 파악 이해하고, 직접 every와 some,

indexOf 정도의 메소드를 직접 구현해 보길 강력 추천에 추천을 거듭한당.(엔돌핀 돌 것이당)

<!DOCTYPE html>
<meta charset="UTF-8">
<script>
const MyArray = function(){
    this.length = 0;       
    return this; 
}

// 아래 주석은 모든 결과 화긴 후, 주석해제 후 결과모양 확인요(찾았다면 재미남!) 
//MyArray.prototype.splice = Array.prototype.splice;

// push 메소드 구현
MyArray.prototype.push = function(pElem){   
        this[this.length] = pElem; 
        this.length++;
        return this;    // 요거이 있으면 멧소드 체인닝
}

// pop 메소드 구현
MyArray.prototype.pop = function(){
        var retVal = this[this.length-1];    
        delete this[this.length-1];
        this.length--;
        return retVal; 
}

//includes 메소드 구현
MyArray.prototype.includes = function(pSearchElem,pIndex){
    var sindex = 0;
    if(pIndex) sindex = pIndex;
    for(let i=sindex; i<this.length; i++){
        if(this[i] == pSearchElem) {
            return true;
        }
    }
    return false;
}


// forEach 메소드 구현
MyArray.prototype.forEach = function(pCallback){
    for(let i=0; i<this.length; i++){
          pCallback(this[i],i);
    }
    return this;  // 메소드 체인닝
}

// map 메소드 구현
MyArray.prototype.map = function(pCallback){
    for(let i=0; i<this.length; i++){
        this[i] = pCallback(this[i],i);
    }
    return this; // 메소드 체인닝
}

// reduce 메소드 구현
MyArray.prototype.reduce = function(pCallback,pInitValue){
    var accumulator = this[0];
    var sindex = 1;
    if(pInitValue){
        accumulator = pInitValue;
        sindex =0;
    }

    for(let i=sindex; i<this.length; i++){
        accumulator = pCallback.call(this,accumulator,this[i],i);
    }
    return accumulator;
}

// filter
MyArray.prototype.filter = function(pCallback){
    var filterArr = [];
    for(let i=0; i<this.length; i++){
        if(pCallback(this[i],i)){
            filterArr.push(this[i]);
        }
    }
    return filterArr;
}

// of 메소드 구현, 이것은 static 구현으로 보면 됨!(체킁!)
MyArray.of = function(...pArgs){
    // MyArray 타입으로 맹글어야 하지만 ,그냥 딴쑨히 찐짜 배열롱
    return [...pArgs];  
}


/******* 맹글었다면 껌쯩 테스통!  **************/
// 생성 체킁
const testArr = new MyArray();
console.log("생성 체킁: ",testArr);

// push 이용 더미 값 넣어보깅(몇개망),체이닝 확인
testArr.push("로제").push("제니").push("리사").push("지수").push("푸시");
console.log("push 체킁: ",testArr);

// pop 체킁, 마지막값이 리턴되고, 배열에선 지워짐
let lastVal = testArr.pop();
console.log("pop 체킁: ",lastVal, testArr);

//includes 체킁, 찾으면 true, 아님 false
let schRslt = testArr.includes("로제");
console.log("includes 체킁: ",schRslt?"있어용":"없는데용");

// forEach 단순 루핑
testArr.forEach((value,index)=>{
    console.log("forEach 체킁: ",value,index);
});

// map 개별요소 값 변환
testArr.map((value,index)=>{
    if(value=="로제"){
        return value + "만만세";
    }
    return value;
});
console.log("map 체킁: ",testArr);

// reduce 전체요소로 연산한 1개 결과
let reduceRslt = testArr.reduce(function(accm,val,index){
    if(index == (this.length-1)){
        return accm + " 만세 " + val + "만세";
    }
    return accm + " 만세 " + val;
});
console.log("reduce 체킁: ", reduceRslt);

// filter 골라내깅
let filteredRslt = testArr.filter((val,index)=>{
    if(index % 2 == 1) return val;
});
console.log("filter 체킁: ", filteredRslt);

// of  static메소드로 단순히 값 나열을 배열롱
// testArr이 아니공 MyArr을 써야 함에 주의!
let ofRslt = MyArray.of("나연","모모","지효","미나","채영");
console.log("of 체킁: ", ofRslt);

</script>

설명은 장농 다리에  , 코드는 기럭지 하니, 한줄 한줄 알아가는 재미가 있을 거시당!

콜백에다 메소드 체인닝까지 점점 익숙해져 가는 기쁨을 긍정적인 당신은 감출 수가 없당. 

 

sort 메소드는 중요해서 일부러 뺐당. 따로 하장!

 

두 사람의 이름이 있다. 한 사람의 이름을 가위로 잘랐다.

하지 말아야 했다. 미신이라 해도 마음을 불편하게 한당. 이미 늦었당.

사건의 이유로 뇌를 찾아와 회반죽을 남긴다. 한 사람의 이름은 그냥 버렸당.

 

Node, React, Angular, Vue, MongoDB 너희들이 단지 자바스크립트라서 그래서 더 좋았당

 

https://www.youtube.com/watch?v=qin_fLuymgE 

 

 

관련글 더보기