웹 스터디

코스 전체목록

닫기

표준 내장 객체의 확장

표준 내장 객체(Standard Built-in Object)는 자바스크립트가 기본적으로 가지고 있는 객체들을 의미한다. 내장 객체가 중요한 이유는 프로그래밍을 하는데 기본적으로 필요한 도구들이기 때문에다. 결국 프로그래밍이라는 것은 언어와 호스트 환경에 제공하는 기능들을 통해서 새로운 소프트웨어를 만들어내는 것이기 때문에 내장 객체에 대한 이해는 프로그래밍의 기본이라고 할 수 있다. 

자바스크립트는 아래와 같은 내장 객체를 가지고 있다. 

  • Object
  • Function
  • Array
  • String
  • Boolean
  • Number
  • Math
  • Date
  • RegExp

이제 우리는 내장객체라는 하늘에서 뚝떨어진 이것들이 무엇인지를 보다 잘 이해할 수 있게 되었다. new가 무엇인지, 함수가 객체를 어떻게 만드는지도 알았다. 또 원한다면 자바스크립트의 내장 객체와 같은 것을 우리도 만들 수 있다는 것도 알았다. 이러한 지식을 바탕으로 좀 더 멋진 일을 해보자.

배열을 확장

배열을 확장해보자. 아래 코드는 배열에서 특정한 값을 랜덤하게 추출하는 코드다. 

var arr = new Array('seoul','new york','ladarkh','pusan', 'Tsukuba');
function getRandomValueFromArray(haystack){
    var index = Math.floor(haystack.length*Math.random());
    return haystack[index];	
}
console.log(getRandomValueFromArray(arr));

이렇게 작성해도 된다! 잘못한 것이 아니다. 하지만 조금 더 세련된 방법은 이 함수를 배열 객체에 포함시키는 것이다. 그렇게하면 마치 배열에 내장된 메소드인 것처럼 위의 기능을 사용할 수 있다.

Array.prototype.rand = function(){
    var index = Math.floor(this.length*Math.random());
    return this[index];
}
var arr = new Array('seoul','new york','ladarkh','pusan', 'Tsukuba');
console.log(arr.rand());

댓글

댓글 본문
  1. seaWater
    2021. 9. 29. 완료
  2. 완료
  3. labis98
    20210822 good!!!
  4. 드림보이
    수강완료했습니다...
  5. 낭만고양이
    수강완료
  6. 다음 Object 강의를 듣고 Prototype에 대해서 약간 더 이해하고 나니 궁금증이 풀렸습니다 ^^;; prototype으로 만들어진 method들은 상속이라는 특성 때문에 하위객체에 임의로 상속될 수 있기 때문에 literal count에는 들어가지 않는것이군요, prototype으로 만들어진 method들을 전부 count한다면 불필요한 혼란만 가중시키고 일반적인 용법에서도 벗어나기 때문에 이렇게 설계된 것 같습니다,,, 당장 이해가 안 가도 진도를 나가다 보면 마법처럼 의문이 풀리는 명강의 입니다,,,
    대화보기
    • 안녕하세요 ? 항상 탁월한 생활코딩 강의로 감사히 코딩 공부를 하고 있습니다.
      초심자인데 한 가지 질문이 있어 자문 구합니다.

      강의에서의 사례를 보던 중에 random이 count되지 않는 점에 의문을 품고
      이것 저것 테스트해 보다가 일단 배열인 arr의 element를 count하는 length에
      object인 random이 포함되지 않을 수 있으므로 arr 배열을 임의로 객체로 변경하고
      object의 키값을 배열로 바꿔주는 Object.keys(객체)라는 명령어를 통해 key 값을
      count하는 테스트를 하였습니다.

      그 결과 prototype을 통해 random을 arr의 method로 생성해줄 때는
      count되지 않던 random이, Capitals라는 생성자를 통해 다른 property들과 함께
      나란히 method로 객체에 포함시켜 주자 count가 되는 것을 발견했습니다.
      arr literal을 실행시켜보아도 역시 prototype으로 생성된 random method는
      literal에 포함되지 않는 반면에 Capitals 생성자로 만들어준 random method는
      리터럴에 다른 property와 나란히 포함되는 것으로 나옵니다.

      javascript에서는 prototype으로 형성된 method와 리터럴이나 생성자로
      생성된 method에는 차이를 두는 것인지요 ?
      아직 prototype도 잘 이해를 못 하고 js에 대한 이해도가 턱없이 부족해 생긴 궁금증인 것 같고,,
      실제로는 method를 객체 리터럴에는 포함시키지 않고 뒤에서 작동하도록 만드는 게
      더 유용하니 prototype으로 method를 지정해 주는 것이 더 유용할 것 같다는 생각도 듭니다.
      제 추측이 맞는지 어떤 건지 궁금합니다.

      1. 생성자 안에서 random을 지정해 준 경우

      function Capitals() {
      this.korea = 'Seoul';
      this.usa = 'Washington DC';
      this.turkey = 'Istanbul';
      this.japan = 'Tokyo';
      this.China = 'Beijing';
      this.random = function(){
      var index = Math.floor(Object.keys(this).length*Math.random());
      return Object.keys(this)[index];
      }
      }

      var arr = new Capitals();
      console.log(arr.random());

      2. prototype을 통해 random을 method로 지정해 준 경우

      function Capitals() {
      this.korea = 'Seoul';
      this.usa = 'Washington DC';
      this.turkey = 'Istanbul';
      this.japan = 'Tokyo';
      this.China = 'Beijing';
      }
      Capitals.prototype.random = function(){
      var index = Math.floor(Object.keys(this).length*Math.random());
      return Object.keys(this)[index];
      }

      var arr = new Capitals();
      console.log(arr.random());
    • Amousk
      좋은강의 감사합니다.
    • 손보선
      밑에 seo.jb 님이 질문하신것처럼, 이렇게 확장했을 때 유효한 스코프가 어떻게 되는지요?
      이렇게 선언한 이후 모든 자바스크립트 코드에서 유효한지, 아니면 해당 블럭에서만 유효한지요?
    • hanel_
      21.3.3
    • cosgenio
      rand를 다시 지우기 전 까지는 표준 Array 객체의 속성이 변경된 것 아닌가요 결국?
      좋은 방식은 아닌 것 같은데
      대화보기
      • 금도끼은도끼
        영구히 변형이 아니라 복사해서 새로운주소에 저장한걸 꺼내서 쓰는거입니다..
        대화보기
        • psyless
          와. 진심
          너무 잘 가르친다.
          감사합니다.
        • 강승
          감사합니다.
        • 박병진
          제나이 23살 너무나 간절한 내꿈과 목표. 정말 감사합니다. 저만의 웹사이트, 웹사이트 쇼핑몰, 웹 비즈니스를 하고싶었는데 이고잉 프로그래머 선생님이 저의 갈증을 매일 해소해줍니다. 프로그래밍 기술을 배우려면 돈이 많이 들어가고 그러는데 선생님은 천사입니다.
        • seo.jb
          한가지 의문이 있습니다. 이렇게 확장한 Array 객체는, 앞으로 영구히 변형된 객체가 아닌가요?
          마치 앞서 상속에서 설명한것 처럼 상위(부모) 객체의 prototype 을 직접 변형해 버린것이라고 생각하는데,
          부모는 변경하지 않고 상속하는 형태로 확장된 새로운 객체를 정의하려면 어떠한 방식이 있는지 궁금합니다.
        • 안상혁
          완벽한 강의에 하찮은 제가 조금 추가하자면....

          1) Math.random 은 0 '이상', 1 '미만'의 수 입니다.
          즉, 1은 포함하지 않게 됩니다.

          2) Math.floor 도 소수점 이하를 제거한다고만 생각하시면
          음의 정수에서는 옳지 않으니 '내림' 개념으로 생각하시기 바랍니다.
          -1.333 은 -2가 됩니다.
        • ironia
          감사합니다~
        • 한강
          오늘도 감사합니다 ~~^^!
          200402
        • 굼벵이
          완료
        • 홍주호
          20191103 완료
        • 박창신
          완료
        • 호두
          고맙습니다
        • 호두
          조금 더 세련된 방법은 이 함수를 배열 객체에 포함시키는 것이다.
        • choon
          감사합니다.
        • 치미
          오 멋있네요
        • 미완성
          20190109
        • 스탐
          감사합니다.
        • moon
          감사합니다.
        • ㄷㄷㄷ
          Math.random 메서드는 [0,1) 사이의 실수를 반환합니다.

          최댓값이 1이 아니라 없습니다.
        • nulgrace
          내장 객체인 Array에 직접 프로토타입을 설정하는 것은 위험하지 않은 건가요? 왠지 웬만해선 건들지 않는 게 좋을 거 같은 영역을 건드는 느낌이 들었습니다. 아무 문제가 없는 건지 궁금합니다. 실무에서 내장객체를 다룰때 직접적으로 prototype을 조작하는 일이 있나요? 아니면 편의상 다른 변수에 내장객체 생성자를 통해 내장객체를 받아오고 새롭게 만든 변수를 사용자정의 내장객체? 같은 걸로 만들어서 사용하나요?
        • 김진홍
          감사합니다!
        • Seo Yun Seok Tudoistube
          먼저, 이고잉님, 황금멍멍이의 건강하고 행복한 이미지처럼 새해도 복많이 받으세요^^

          그럼, Ultra.prototype.속성 으로 하는 것과 함수.apply(Ultra) 의 차이는 재사용이 가능하냐로 보면 될까요?
          실무에서 prototype 는 상속으로 쓸때, apply() 는 jQuery 에서 본듯한데 용도가 어떻게 다른지 궁금합니다.

          지금 Vue 공부를 하다가 다시 자바스크립트랑 CSS 공부하다가 이 부분에서 질문을 드리네요. 감사합니다^^*
          대화보기
          • egoing
            물론이죠~ 함수 정의하는 것은 흔한 일이랍니다
            대화보기
            • Seo Yun Seok Tudoistube
              내장객체에 사용자정의 함수를 추가하면 정말 편리할거 같은데, 질문이 생겼습니다.
              사용자 정의함수를 많이 쓰면 관리가 중요할거 같은데, 실무에서 여러 사람이 함께 작업하실때도 이 방법을 많이 쓰시나요?
            • 이영채
              언제나 감사합니다!
            • 박인호
              12-19
              수강완료.
              prototype이라는 녀석이 상당히 강력하고 중요한 녀석이군요.
            • 고스트프리
              감사합니다.
            • GoldPenguin
              완료했습니다.
            • 송성태
              정말 감사합니다.
              거인의 어깨에 올라선다는 느낌이 듭니다.
              내장표준 함수를 이용해서 사용자의 힘을 한층 키우는 것 같습니다.
              처음에는 어려웠는데 객체, 정말 재미있네요.
              이제 시작이지만 최선을 다하겠습니다.
              다시 한번 감사합니다!
            • epsxk82
              네.
              var arr = new Array('seoul', 'new york', 'ladrkh', 'pusan', 'tsukuba');
              var arr = ['seoul', 'new york', 'ladrkh', 'pusan', 'tsukuba'];
              둘다 배열 객체입니다.

              var arr = new Array {Korea:'seoul', USA: 'new york', India: 'ladrkh', Korea: 'pusan', India:'tsukuba'};
              이것도 배열객체맞습니만.
              위의 문장은 문법에러인걸로 알고 있습니다.^^;
              생성자 함수와 객체 리터럴 표현식( {Korea:'seoul', USA: 'new york', India: 'ladrkh', Korea: 'pusan', India:'tsukuba'})이 같이 오는 것은 문법 에러로 알고 있습니다^^;

              변수, 객체의 개념을 아직 햇갈리시는 거 같습니다... 이는 시간이 되면 따로 설명을 드릴께요.^^
              대화보기
              • epsxk82
                네.
                var arr = new Array('seoul', 'new york', 'ladrkh', 'pusan', 'tsukuba');
                var arr = ['seoul', 'new york', 'ladrkh', 'pusan', 'tsukuba'];
                둘다 배열 객체입니다.

                var arr = new Array {Korea:'seoul', USA: 'new york', India: 'ladrkh', Korea: 'pusan', India:'tsukuba'};
                이것도 배열객체맞습니만.
                위의 문장은 문법에러인걸로 알고 있습니다.^^;
                생성자 함수와 객체 리터럴 표현식( {Korea:'seoul', USA: 'new york', India: 'ladrkh', Korea: 'pusan', India:'tsukuba'})이 같이 오는 것은 문법 에러로 알고 있습니다^^;

                변수, 객체의 개념을 아직 햇갈리시는 거 같습니다... 이는 시간이 되면 따로 설명을 드릴께요.^^
                대화보기
                • epsxk82
                  질문내용을 잘 이해를 못하겠네요.
                  문제가 있는 코드를 올려봐주세요.
                  대화보기
                  • epsxk82
                    잘못이해하신거 같습니다.

                    객체를 생성하는 선언은 두가지가 있다고 두가지가 있다고 말씀드렸죠?
                    1> var v = new 생성자 함수이름();
                    또는
                    2> var v = 리터럴 값 표현;

                    배열객체 생성의 경우,
                    var arr = new Array('seoul', 'new york', 'ladrkh', 'pusan', 'tsukuba');
                    은 1>에 해당하는 거고
                    var arr = ['seoul', 'new york', 'ladrkh', 'pusan', 'tsukuba'];
                    은 2>에 해당하는 겁니다. 배열의 경우, 리터럴 값 표현에 특수하게 대괄호[]를 쓰는 겁니다.

                    참고로, 사용자가 정의하는 객체의 경우, 2>번 즉 리터럴 값 표현으로 객체를 생성할 경우에
                    var custuomObj = {'firstField':1, 'secondField':'second};
                    중괄호{}을 쓰는데, 배열의 대괄호[]과 햇갈리시지 마세요.
                    대화보기
                    • epsxk82
                      this가 포함된 표현식이 var arr.. 이부분 보다 위에 위치해 있어서 햇갈리시는 거 같습니다만.^^
                      아마도 this가 windows객체가 아니냐 생각하실 수 있겠습니다만.

                      Array.prototype.rand = function(){
                      var index = Math.floor(this.length*Math.random());
                      return this[index];
                      }
                      이 이야기는 'Array객체가 rand라는 이름의 멤버 메소드(함수)를 가지고 있고, 그 함수의 정의는 다음과 같다'라고 선언하는 겁니다.
                      그럼 arr.rand()를 실행하면 어떤일이 벌어질까요? rand라는 함수는 Array객체의 멤버이기 때문에 rand함수 본문의 this객체는 전역객체 windows객체가 아닌 Array객체인 arr을 가르키게 되는 겁니다.(메소드의 경우 메소드 정의 안에 this키워드는 그 메소드가 소속된 객체를 가르키게 된다고 앞 수업에서 배웠습니다.^^)

                      this라는 키워드는 함수가 정의된 위치에서의 문맥이 아닌 그 함수가 실행되는 시점에서의 문맥과 연관된 키워드입니다.

                      function f()
                      {
                      return this;
                      }

                      function obj()
                      {
                      this.value = 1;
                      }

                      1> var x = f() ---> x는 전역객체 window
                      var v = new obj();
                      2> var x2 = f.apply(v); ---> x2는 obj

                      위의 2>의 this는 obj객체를 나타냅니다. apply라는 함수가 함수f를 v라는 obj객체의 메소드로 잠시동안 등록시키고 f()라는 함수를 obj객체의 메소드로서 실행시키고 f를 obj의 메소드에서 제외시킵니다. 현재 f라는 함수는 obj의 메소드로서 실행되고 있으니 this는 obj가 됩니다.
                      대화보기
                      • epsxk82
                        egoing님께서 언급하셨던거 같습니다만, 우리는 객체를 생성하는 두가지 방법을 알고 있습니다.
                        1> var v = new 생성자 함수이름();
                        또는
                        2> var v = 리터럴 값 표현;

                        신시내티님이 이야기 하시는 괄호()를 쓴 경우는, 생성자 함수를 호출해서 (배열)객체를 생성한 1번째 경우입니다.
                        위의 예를 들면,
                        var arr = new Array('seoul', 'new york', 'ladrkh', 'pusan', 'tsukuba');
                        배열객체의 생성자 함수를 호출하여 배열객체를 생성하였습니다.

                        신시내티님이 이야기 하시는 대괄호[]를 쓴 경우는, 배열의 리터럴값을 표현하는 2번째 경우에 해당합니다.
                        즉,
                        var arr = ['seoul', 'new york', 'ladrkh', 'pusan', 'tsukuba'];
                        배열의 리터럴 값을 명시하여 (배열)객체를 생성했습니다.
                        리터럴 값이란 (변수도 아니고, 함수도 아닌) 실제 객체에 저장될 데이터 값 그 자체를 이야기 하는 것입니다.(var a = 1이면 1이 리터럴 값, var b = "string"이면 string이 리터럴 값입니다)

                        근데 생성자 함수에 []를 쓰게되면

                        var arr = new Array['seoul', 'new york', 'ladrkh', 'pusan', 'tsukuba'];
                        이것은 문법에러입니다.
                        생성자 함수도 함수의 일종이고 자바스크립트에서는 함수를 호출할때 ()를 쓰라고 우리는 이미 배웠지요^^
                        정리하자면,
                        생성자함수를 호출해서 배열객체를 생성할 때는 괄호()를 쓰셔야 하고 대괄호[]는 안되며,
                        리터럴값을 표현하여 배열객체를 생성할 때에 대괄호[]를 쓰시는 겁니다.
                        대화보기
                        • 더나은삶
                          잘 보고 있습니다. 감사합니다.
                        • sealwind
                          간단한 로또 번호 생성기 ㅡ ㅡ;;
                          for (var i = 0; i < 6; i++) {
                          document.write(Math.floor(Math.random()*45)+1+'<br />');
                          }
                        • Seo Yun Seok Tudoistube
                          마치 자바스크립트 내장객체의 메서드인것처럼 사용한다면, 훨씬 간결하고 재사용성도 높아져서 좋으네요.
                          감사합니다^_____^!!!
                        • crable
                          감사합니다.
                        버전 관리
                        egoing
                        현재 버전
                        선택 버전
                        graphittie 자세히 보기