모든 수업과 소스코드는 아래 주소에 있습니다. opentutorials.... 전체 지식의 관계는 아래 지식지도를 참고해주세요. seomal.org 생활코딩은 일반인에게 프로그래밍을 알려주는 활동입니다. 더 많은 정보를 원하시면 opentutorials.o... 를 방문해주세요.
드디어 이해 했습니다. 1년만에 이해했습니다.. 왜 머리가 나쁠까 자책했습니다. 하지만 포기하지 않았습니다. 1. 프로토타입의 의미란? : 객체들이 공통으로 사용하는 속성값이다. 2.프로토타입이 없을 떄의 비효율적인 점은 무엇인가? :객체를 생성할 떄마다 같은 동작을 하는 중복적인 메소드가 메모리에 계속 생긴다. => 성능 저하, 메모리 낭비 생김. 3. 프로토타입을 사용하면 좋은 점은 무엇인가? 객체들이 공통으로 사용하는 속성값을 정의해서 객체가 생성할때 마다 같은 속성 값을 만드는 과정을 생략해, 성능 향상과 메모리를 효율적으로 이용할 수 있게 해준다. 문법 : 생성자 함수명.prototype.함수명 = function(){ } 로 한번만 정의. 보충 설명 : 프로토타입은 객체를 정의하는 시점이 아닌, 자신이 필요한 시점에서 정의 할 수 있기때문에 메모리의 이점이 있다. 또한 프로토타입은 생성된 모든 객체가 공통으로 사용할 수 있고 재정의가 가능하기 떄문에 커스터마이징이 가능하다.
프로토 타입의 의미는 객체가 생성될때마다 해당 객체의 메소드를 만들어 메모리에 할당을 해야 하는데 그렇게 하지않고 생성자의 프로토타입에 정의함으로서 다른 모든 객체들이 참조하여 사용할 수 있도록 하여 메모리를 효율적으로 사용할 수 있도록 하는 장점과 메소드의 재정의가 필요한 객체들은 상황에 맞게 자신만 사용가능한 메소드를 재정의 할수 있어 유지보수에도 많은 도움이 됩니다.
1. 프로토타입의 의미란? -객체들이 공통으로 사용하는 속성입니다. 2. 생성자 함수 안에 프로토타입을 이용하지 않고 메서드나 프로퍼티를 생성하면 어떤 비효율이 발생하나요? -각 인스턴스마다 다른 프로퍼티나 메서드를 정의하기 때문에 쓸데없이 메모리를 잡아먹게 되서 코드 최적화에 부정적인 영향을 주게 됩니다. 3. 프로토타입을 통해 그 비효율을 어떻게 극복하게 되나요? -프로토타입을 통해 생성자 함수에 공통적으로 사용할 메서드나 프로퍼티를 생성하게 되면, 각 인스턴스에 숨겨진 프로퍼티인 '__proto__'를 통해 특정 인스턴스가 생성자 함수 프로토타입에 있는 메서드나 프로퍼티를 사용하게 됩니다. 만약 특정 인스턴스에 다른 메서드나 프로퍼티를 주고 싶으면 특정 인스턴스 메서드나 프로퍼티만 따로 정의하거나 선언하면 됩니다.
prototype은 특정 주소를 향해 있는 것 같네요. 그래서 생성자 함수가 생성 될 때 sum 생성자 함수 안에 있는 주소를 바라보게 되고, 같은 생성자 함수를 사용하여 100개 1000개를 만들더라도 생성자 함수를 통해 생성된 함수의 sum은 모두 동일한 주소 값을 가리키는 것. 그래서. Person.prototype.sum이 수정 되면 생성자 함수가 모두 같은 곳을 바라보기 때문에 모두에게 영양을 받는 것 같아요.
1. 프로토타입이란? 객체의 DNA. 자신이 속해있는 객체1이 있고, 외부에서 객체1의 하나의 DNA, 프로퍼티가 된다. 프로토타입 프로퍼티의 소속이 객체1이기 때문에, 객체1이 영향을 주는 것들에 동일하게 영향을 준다. 2. 프로토타입을 사용하지 않았을 때 프로토타입 프로퍼티를 사용하지 않고 하나의 기능으로 객체1에 속해있을 때, 객체1을 사용하고자 하는 모든 데이터들에게 동일하게 영향을 줄 수는 있지만, 데이터들 마다 호출이 반복되고, 저장이 반복된다면 메모리에 언젠가 무리를 주게 된다. 그리고 모든 데이터들 중 몇몇의 데이터가 다른 기능을 사용하고자 할 때, 그 데이터들에 찾아가서 다른 기능을 수정하게 되는데, 그렇게 되면 "원래 객체의 기능 호출됨 + 현재 수정된 기능 호출됨" 총 2번의 동작하기 때문에, 이는 프로그램을 무겁게 만든다. 3. 프로토타입을 사용할 때 외부로 나와 프로토타입 프로퍼티를 사용하여 기능을 정해놓으면, 그 기능은 한번의 호출됨으로 모든 데이터에 영향을 줄 수 있다. 무한한 반복과 저장이 1로 줄어드는 셈! 이는 프로그램에게 큰 효율성을 가져다준다.
prototype이란 객체가 생성자 함수를 호출할 때마다 그 안에 있는 메소드(함수)를 반복적으로 호출하지 않도록 도와준다. 즉, 메모리의 낭비를 줄인다. 대신 prototype은 객체가 공통(메모리 효율이 증대)으로 사용할 수 있고 필요하다면 개별 객체가 생성자 함수를 재정의 할 수 있기 때문에 커스터마이징에도 이점이 있다. 쉽게 말해서, 특정 객체의 함수를 변경하고 싶다면 그 객체만 변경함으로써 기존의 prototype에는 영향을 주지 않는다
1)프로토타입은 상속의 의미로 부모가 자녀로써 물려주어 해당 참조 값이 없을경우 위로 올라가 해당 값을 참조합니다. 2)직접 정의를 할 경우, 해당 메소드중에 사용하지 않는 메소드또한 정의가 되기떄문에, 직접정의되는 메소드들이 많을 경우, 필요치 않는 메소드 떄문에 메모리의 비효율이 발생합니다 3)프로토타입을 정의 햇을 경우, 필요한 시점에서 정의할 수 잇으며, 직접정의 받는 개체에서 필요치않은 프로토타입은 참조하지않으면 되며, 필요할 경우 프로토타입을 참조하여 비효율이 줄어듭니다. 또한 프로토타입을 물려받는 많은 값들중에 부분수정을 필요로하는 프로토타입이 있으면, 그 객체 안에서 프로토타입을 재정의하여 그값만을 수정할 수 있습니다.
1. prototype이 갖는 의미: prototype은 원형이다. 객체의 특정한 메소드를 호출하려 할 때, 그 객체가 해당 메소드를 가지고 있다면 그것을 바로 실행한다. 하지만, 그 객체가 해당 메소드를 가지고 있지 않는다면, prototype이 해당 메소드를 가지고 있는지 확인한 후, 가지고 있다면 그 메소드를 실행한다. 2. prototype을 사용하지 않고 생성자 함수 안에서 메소드를 직접 정의할 경우 발생하는 비효율, 그리고 prototype을 이용함으로써 그것을 어떻게 해결했는가: 생성자 함수 안에서 메소드를 정의할 경우 새로운 객체를 생산할 때마다 메소드를 정의하는 코드가 싱행되어야 하고 같은 메소드가 중복 실햄되면서 메모리를 낭비하게된다. 반면에 prototype에서 메소드를 정의한다면 단 한번만 함수를 정의하고도 생성된 객체들이 해당 메소드를 호출할 수 있게 되므로 메모리를 절감하는 효과를 얻을 수 있다.
prototype을 수납상자 개념으로 바라본다면, constructor의 속성들이 잘 정리된 박스안에, 나중에 필요할 때만 꺼내서 볼 수있는 함수들을 상자에 다시한번 정리하는 것이다. 이로인해 나중에 필요할 때 찾아서 꺼내보는것도 쉽고, 첫번째 constructor박스를 꺼내볼 때마다 불필요하게 나타나지 않아 메모리가 불필요하게 사용되는 것을 방지할 수 있다.
프로토타입은 생성자 함수 밖에다가 정의하며 같은 생성자 함수에서 생성한 객체들은 모두 프로토타입으로 정의한 매소드를 사용할 수 있습니다. 그래서 메모리 관점에서도 객체 안에 정의할 때보다 효율적이며 수정시에도 객체 안에 매소드를 정의한 경우 처럼 일일이 수정할 필요가 없습니다. 즉, 프로토타입만 수정해주면 나머지 객체들도 수정된 매소드를 사용하게 되어 효율적으로 수정이 가능합니다.
마지막즈음에 kim.sum = function(){ return 'this : ' 가 정의 된 상태임에 불구하고 그래도 prototype의 함수 결과를 리턴하고 싶을때는 어떻게 하나요? 이것 저것 찾아보다가 __proto__라는 것을 봤는데, kim.__proto__.sum() 을 하니까 'prototype:' 으로는 바뀌는데 그 뒤에 sum 값이 NaN으로 출력됩니다.. 혹시 답변 주실수 있으신가요?
맞습니다. 생성자에 있는 것은 생성할 때 만들어지는 것이고, 생성한 이후에 변경작업을 하지 않는다면 프로토타입이 갖는 유지보수의 편의성은 존재하지 않습니다. 제 말은 이미 만들어진 객체의 메서드를 변경하려면 수정작업을 다시 해줘야 한다는 의미였습니다. 제가 불명확하게 설명을 했나보군요.
1. 프로토타입은 '원형' 이란 의미를 갖고 있습니다. => 후에 자신이 원하는 몇몇 객체들에게 '원형과 다른' 함수를 만들 수 있다는 대목에서 '원형'이라는 단어가 참 직관적인 것 같습니다. 2. 모든 객체가 공통으로 갖게 될 부분이 객체 생성을 매번 할때마다 메모리에 할당된다는 것은 비효율적입니다. => 사실 다른 객체지향 언어로 프로그래밍 할 떄에는 그냥 생각없이 넘어갔던 것이었는데, 이 강의에서 새삼 놀라고 이 점에 대해 고민하게 되었습니다. 다른 언어들은 이 문제점을 어떻게 극복하는 것일까요..?? 동작방법이 다른걸까요.. 저는 지식이 얕아서 잘 모르겠습니다ㅎㅎ; 3. 속성/메소드를 프로토타입을 이용하여 바깥에 빼둠으로서, 객체가 생성될때마다 공통부분이 메모리에 중복되어 쌓이는 일이 없도록 할 수 있습니다. => 그렇지만, 선생님께서 말씀하신대로 데이터 같은 속성들은 아무래도 객체가 갖고 있는 것이 객체지향 프로그래밍에 더 맞는 것 같습니다...
컨스트럭터를 이용해 데이터와 메소드를 정의할 때 데이터는 주로 컨스트럭터 안에 저장, 메소드는 프로토타입을 이용해 따로 생성한다. 이유는 새로운 객체를 생성할 때마다 객체 자체에 저장 되어 있지 않은 메소드를 정의하지 않음으로써 속도를 빠르게 하고 메모리를 아낄 수 있고, 또한 모든 객체의 공통된 메소드 수정이 용이하기 때문이다. 메소드를 호출할 때, 자바스크립트는 객체내에 있는 메소드를 먼저 찾고, 객체 내에 호출한 메소드가 없을 때 비로소 프로토타입으로 정의한 메소드를 찾는다.
정리. (prop, value, func, [" "])은유적 표현입니다. 실제 코드는 저래쓰심안되요. 1. 인스턴스가 가져야 할 고유 Data는 생성자 내부에서 this.["prop"] = value; 로 초기화 할것. 2. 그 클래스의 모든 인스턴스가 가져야할 공통분모는 클래스.prototype.["prop & func"] = value & func(){}; 이렇게 값이든 함수든 공통 맴버로 사용.
강의 복습: (강의 내에서 정의되었던) Person 생성자를 이용하여 이미 일억개의 객체(예를 들면 User)를 생성한 직후, sum함수의 return 값이 잘못되었다는 것을 깨달았다고 가정해봅니다. 이 때 Person 생성자 내의 sum 함수의 return값을 수정한들, 이미 생성된 객체들의 sum함수는 변경되지 않습니다. 앞으로 생성될 객체들에서부터 적용되겠죠. 그럼 이미 생성된 객체들에 대해서는 모두 직접 변경해주어야합니다. (못할짓이죠ㅎ) 그렇기 때문에 prototype을 사용하게 됩니다. 생성자로부터 분리하여, 함수를 매번 생성자 내에서 정의하면서 발생했던 메모리 및 성능 비효율성을 해결하고, 함수 자체의 수정도 자유로워진 것이죠. Prototype의 뜻은 '원형'이므로 각 객체가 자기 자신의 함수를 커스터마이징하지 않는 한, 모든 객체가 동일하게 사용할 수 있는 기본 형식 같은 의미가 아닐까 생각합니다.
이 때 Person 생성자 내의 sum 함수의 return값을 수정한들, "이미 생성된 객체들의 sum함수는 변경되지 않습니다." 앞으로 생성될 객체들에서부터 적용되겠죠. 그럼 이미 생성된 객체들에 대해서는 모두 직접 변경해주어야합니다. -> Person 생성자 내의 sum 함수를 수정하면 생성된 객체들의 sum 함수가 변경되기 때문에 출력값이 변경되는 거 아닌가요? 제가 무언가 잘못 생각하고 있는 게 있다면 지적 부탁드립니다.
- JS에서 프로토타입이란? : JS에선 '원형'이란 의미로서 함수 등의 객체에게 'DNA' 같은 역할을 하는 것이다. 자바 같은 데선 클래스를 통해 상속을 구현한 것과 달리, JS에선 이 프로토타입(prototype)이란 속성을 통해 상속을 구현하도록 되어 있다. 최상위 조상 객체부터 최하단의 자손 객체에 이르기까지 prototype속성을 통해 연결시킨 '상속관계'를 만듬으로써 'prototype chain'모양을 갖춘 상속관계가 완성되어진다. - 프로토타입을 사용하지않고 생성자 함수 안에서 메소드나 속성을 정의하게 되면 어떤 비효율이 발생하게 되는가? : 매 객체가 생성될 때 마다 해당 메소드/속성이 '반복적으로' 계속 생겨나게 되고, 이는 동일한 내용이 메모리를 중복적으로 차지하여 '낭비'가 발생하게 된다. 객체 숫자가 많아질 수록 이는 더욱 시스템에 부담이 된다. - 그 비효율을 프로토타입을 통해 어떻게 극복하게 되었는가? : 함수 안에 '중복적인 속성/메소드'를 정의해놓지 않고, 해당 함수의 원형(prototype)에 만들어 박아놓으면 그 함수로부터 파생된 모든 객체들은 해당 속성/메소드를 모두 접근해 이용할 수 있게 된다. 이를 통해 중복적인 내용이 반복생성되는 것을 막고 메모리의 낭비를 막을 수 있다. 감사합니다 선생님
제가 이해한 바로는 이런거같아요. 사천요리 전문 중국집이 있어요. 그 가게에서는 탕수육을 시켜도 기본으로 사천 탕수육이 나오고, 짜장면을 시켜도 사천 짜장면이 나오죠. 사천화 시킨다 라는 함수가 프로토타입에 정의되어있기때문이죠. 매운걸 못먹는 사람은 별도로 ‘안맵게 해주세요’ 라고 주문할테고, 주방장은 그 인스턴스의 음식만 별도로 처리하겠죠. 만약 프로토타입에 ‘사천화 시킨다’ 라는 함수가 정의되어있지않다면 모든 주문마다 주방장과 서버, 손님은 “맵게?” > “손님 맵게해드릴까요?” > “음 얼마나 매워요?” > “신라면보다 매워요” > “네 그럼 맵게해주세요” > “주방장님 맵게요” 이 과정을 겪어야하고, 그건 너무 비효율적이기때문에 프로토타입을 따로 정의한게 아닐까요?
Prototype은 생성자 함수로 찍어낸 객체 안에 들어갈 메서드의 기본 제작 청사진이라고 할 수 있다. 객체 공장에서 객체를 찍어내는 기계에게 별도로 새로운 형태의 객체를 주문 제작하지 않는 이상 기계는 Prototype대로 객체를 찍어낸다. Prototype 없이 생성자 함수를 호출할 때마다 새로 메서드를 만들면 메모리를 낭비하게 된다. 참고할 기본 형태가 없어서 객체 찍는 기계가 힘든 것이다. Prototype은 객체 찍는 기계에게 별도의 명령을 내리지 않는 한 그대로 만들면 되는 설계도를 제공한다. 기계도 덜 힘들고, 프로그래머도 코드를 줄일 수 있다.
프로토 타입 속성을 이용해서 메소드를 객체 생성자 함수 내에 두지 않고 분리할 수 있습니다. 이렇게 하면 객체가 생성될 때마다 메소드를 호출하지 않고, 해당 메소드가 필요한 경우에만 호출하여 사용할 수 있으니 메모리 성능이 높아진다고 이해했어요. 추가적으로, 생성된 특정 객체의 속성을 직접 지정하는 경우는 프로토타입의 속성보다 우선한다고 보았습니다. 예제로 만들어주신 코드에서는 kim.sum 선언문이 Person.prototype.sum 선언문이 보다 아래에 있기 때문에 우선한 것이 아닌가 했는데 직접 순서를 바꿔봐도 kim.sum이 우선되어 적용되네요~
생성자 함수로 생성되는 모든 객체의 인스턴스가 공유할 원형을 담아내는 객체로 메모리의 효율과 성능의 이점을 가져올 수 있고, 특별하게 메소드를 다르게 해야 하는 경우에는 그 객체에 맞는 메소드를 재정의 할 수 있다. prototype이 아닌 기존의 방식을 사용한다면 같은 객체를 무수히 많이 생성한다고 할 때, 성능과 메모리에 좋지 않아 생산성이 떨어진다.
Date 라는 함수는 인자로 날짜를 주면 분명 getDate 나 getMonth 같은 메서드로 마치 인자 처럼 활용하는데 아무리 봐도 프로토타입이나 생성자 객체 내에 어떠한 프로퍼티로도 주어지지 않길레 도대체 왜 이런지 궁금하여 Date 라는 함수의 native code를 볼 방법이 없을까 싶어 검색을 해보니 c 나 c++언어로 만들어져 있다고 하네요. 그래서 포기했습니다. 자바스크립트의 native code는 c 나 c++언어로 만들어진다고 합니다.
드디어 이해 했습니다. 1년만에 이해했습니다.. 왜 머리가 나쁠까 자책했습니다. 하지만 포기하지 않았습니다.
1. 프로토타입의 의미란?
: 객체들이 공통으로 사용하는 속성값이다.
2.프로토타입이 없을 떄의 비효율적인 점은 무엇인가?
:객체를 생성할 떄마다 같은 동작을 하는 중복적인 메소드가 메모리에 계속 생긴다. => 성능 저하, 메모리 낭비 생김.
3. 프로토타입을 사용하면 좋은 점은 무엇인가?
객체들이 공통으로 사용하는 속성값을 정의해서 객체가 생성할때 마다 같은 속성 값을 만드는 과정을 생략해, 성능 향상과 메모리를 효율적으로 이용할 수 있게 해준다.
문법
: 생성자 함수명.prototype.함수명 = function(){ } 로 한번만 정의.
보충 설명
: 프로토타입은 객체를 정의하는 시점이 아닌, 자신이 필요한 시점에서 정의 할 수 있기때문에 메모리의 이점이 있다. 또한 프로토타입은 생성된 모든 객체가 공통으로 사용할 수 있고 재정의가 가능하기 떄문에 커스터마이징이 가능하다.
프로토 타입의 의미는 객체가 생성될때마다 해당 객체의 메소드를 만들어 메모리에 할당을 해야 하는데 그렇게 하지않고 생성자의 프로토타입에 정의함으로서 다른 모든 객체들이 참조하여 사용할 수 있도록 하여 메모리를 효율적으로 사용할 수 있도록 하는 장점과 메소드의 재정의가 필요한 객체들은 상황에 맞게 자신만 사용가능한 메소드를 재정의 할수 있어 유지보수에도 많은 도움이 됩니다.
요약감사합니다~~
1. 프로토타입의 의미란?
-객체들이 공통으로 사용하는 속성입니다.
2. 생성자 함수 안에 프로토타입을 이용하지 않고 메서드나 프로퍼티를 생성하면 어떤 비효율이 발생하나요?
-각 인스턴스마다 다른 프로퍼티나 메서드를 정의하기 때문에 쓸데없이 메모리를 잡아먹게 되서 코드 최적화에 부정적인 영향을 주게 됩니다.
3. 프로토타입을 통해 그 비효율을 어떻게 극복하게 되나요?
-프로토타입을 통해 생성자 함수에 공통적으로 사용할 메서드나 프로퍼티를 생성하게 되면, 각 인스턴스에 숨겨진 프로퍼티인 '__proto__'를 통해 특정 인스턴스가 생성자 함수 프로토타입에 있는 메서드나 프로퍼티를 사용하게 됩니다. 만약 특정 인스턴스에 다른 메서드나 프로퍼티를 주고 싶으면 특정 인스턴스 메서드나 프로퍼티만 따로 정의하거나 선언하면 됩니다.
prototype은 특정 주소를 향해 있는 것 같네요. 그래서 생성자 함수가 생성 될 때 sum 생성자 함수 안에 있는 주소를 바라보게 되고, 같은 생성자 함수를 사용하여 100개 1000개를 만들더라도 생성자 함수를 통해 생성된 함수의 sum은 모두 동일한 주소 값을 가리키는 것. 그래서. Person.prototype.sum이 수정 되면 생성자 함수가 모두 같은 곳을 바라보기 때문에 모두에게 영양을 받는 것 같아요.
1. 프로토타입이란?
객체의 DNA.
자신이 속해있는 객체1이 있고, 외부에서 객체1의 하나의 DNA, 프로퍼티가 된다.
프로토타입 프로퍼티의 소속이 객체1이기 때문에, 객체1이 영향을 주는 것들에 동일하게 영향을 준다.
2. 프로토타입을 사용하지 않았을 때
프로토타입 프로퍼티를 사용하지 않고 하나의 기능으로 객체1에 속해있을 때,
객체1을 사용하고자 하는 모든 데이터들에게 동일하게 영향을 줄 수는 있지만,
데이터들 마다 호출이 반복되고, 저장이 반복된다면 메모리에 언젠가 무리를 주게 된다.
그리고 모든 데이터들 중 몇몇의 데이터가 다른 기능을 사용하고자 할 때, 그 데이터들에 찾아가서 다른 기능을 수정하게 되는데, 그렇게 되면 "원래 객체의 기능 호출됨 + 현재 수정된 기능 호출됨" 총 2번의 동작하기 때문에, 이는 프로그램을 무겁게 만든다.
3. 프로토타입을 사용할 때
외부로 나와 프로토타입 프로퍼티를 사용하여 기능을 정해놓으면,
그 기능은 한번의 호출됨으로 모든 데이터에 영향을 줄 수 있다.
무한한 반복과 저장이 1로 줄어드는 셈!
이는 프로그램에게 큰 효율성을 가져다준다.
prototype이란 객체가 생성자 함수를 호출할 때마다 그 안에 있는 메소드(함수)를 반복적으로 호출하지 않도록 도와준다. 즉, 메모리의 낭비를 줄인다. 대신 prototype은 객체가 공통(메모리 효율이 증대)으로 사용할 수 있고 필요하다면 개별 객체가 생성자 함수를 재정의 할 수 있기 때문에 커스터마이징에도 이점이 있다.
쉽게 말해서, 특정 객체의 함수를 변경하고 싶다면 그 객체만 변경함으로써 기존의 prototype에는 영향을 주지 않는다
대신 prototype은 객체가 공통(메모리 효율이 증대)으로 사용할 수 있고 이부분에서 저도이해했습니다 감사합니다 ㅎㅎ
강의 잘 보고 있습니다.
1)프로토타입은 상속의 의미로 부모가 자녀로써 물려주어 해당 참조 값이 없을경우 위로 올라가 해당 값을 참조합니다. 2)직접 정의를 할 경우, 해당 메소드중에 사용하지 않는 메소드또한 정의가 되기떄문에, 직접정의되는 메소드들이 많을 경우, 필요치 않는 메소드 떄문에 메모리의 비효율이 발생합니다 3)프로토타입을 정의 햇을 경우, 필요한 시점에서 정의할 수 잇으며, 직접정의 받는 개체에서 필요치않은 프로토타입은 참조하지않으면 되며, 필요할 경우 프로토타입을 참조하여 비효율이 줄어듭니다. 또한 프로토타입을 물려받는 많은 값들중에 부분수정을 필요로하는 프로토타입이 있으면, 그 객체 안에서 프로토타입을 재정의하여 그값만을 수정할 수 있습니다.
1. prototype이 갖는 의미: prototype은 원형이다. 객체의 특정한 메소드를 호출하려 할 때, 그 객체가 해당 메소드를 가지고 있다면 그것을 바로 실행한다. 하지만, 그 객체가 해당 메소드를 가지고 있지 않는다면, prototype이 해당 메소드를 가지고 있는지 확인한 후, 가지고 있다면 그 메소드를 실행한다.
2. prototype을 사용하지 않고 생성자 함수 안에서 메소드를 직접 정의할 경우 발생하는 비효율, 그리고 prototype을 이용함으로써 그것을 어떻게 해결했는가: 생성자 함수 안에서 메소드를 정의할 경우 새로운 객체를 생산할 때마다 메소드를 정의하는 코드가 싱행되어야 하고 같은 메소드가 중복 실햄되면서 메모리를 낭비하게된다. 반면에 prototype에서 메소드를 정의한다면 단 한번만 함수를 정의하고도 생성된 객체들이 해당 메소드를 호출할 수 있게 되므로 메모리를 절감하는 효과를 얻을 수 있다.
prototype을 수납상자 개념으로 바라본다면, constructor의 속성들이 잘 정리된 박스안에, 나중에 필요할 때만 꺼내서 볼 수있는 함수들을 상자에 다시한번 정리하는 것이다. 이로인해 나중에 필요할 때 찾아서 꺼내보는것도 쉽고, 첫번째 constructor박스를 꺼내볼 때마다 불필요하게 나타나지 않아 메모리가 불필요하게 사용되는 것을 방지할 수 있다.
프로토타입은 생성자 함수 밖에다가 정의하며 같은 생성자 함수에서 생성한 객체들은 모두 프로토타입으로 정의한 매소드를 사용할 수 있습니다.
그래서 메모리 관점에서도 객체 안에 정의할 때보다 효율적이며 수정시에도 객체 안에 매소드를 정의한 경우 처럼 일일이 수정할 필요가 없습니다.
즉, 프로토타입만 수정해주면 나머지 객체들도 수정된 매소드를 사용하게 되어 효율적으로 수정이 가능합니다.
마지막즈음에 kim.sum = function(){ return 'this : ' 가 정의 된 상태임에 불구하고 그래도 prototype의 함수 결과를 리턴하고 싶을때는 어떻게 하나요? 이것 저것 찾아보다가 __proto__라는 것을 봤는데, kim.__proto__.sum() 을 하니까 'prototype:' 으로는 바뀌는데 그 뒤에 sum 값이 NaN으로 출력됩니다.. 혹시 답변 주실수 있으신가요?
프로토타입에서 메모리 장점말고 1억개를 동시에 수정할수 있다는건 생성자 안에 있는 메소드를 수정해도 1억번 수정하지 않고 인스턴스들을 바꿀수 있는것 아닌가요??
맞습니다. 생성자에 있는 것은 생성할 때 만들어지는 것이고, 생성한 이후에 변경작업을 하지 않는다면 프로토타입이 갖는 유지보수의 편의성은 존재하지 않습니다. 제 말은 이미 만들어진 객체의 메서드를 변경하려면 수정작업을 다시 해줘야 한다는 의미였습니다. 제가 불명확하게 설명을 했나보군요.
@@coohde 감사합니다~! 강의 너무 잘보고 있습니다!! :)
저도 하고 싶은 질문을 해주셨네요! 감사합니다!
답글을 봐도 이해가 잘 안되네요. 혹시 이해하셨으면 설명 부탁드릴 수 있을까요?
@@coohde 답글을 봐도 이해가 잘 안되네요. 혹시 다른 문장으로 설명 부탁드릴 수 있을까요?
1. 프로토타입은 '원형' 이란 의미를 갖고 있습니다.
=> 후에 자신이 원하는 몇몇 객체들에게 '원형과 다른' 함수를 만들 수 있다는 대목에서 '원형'이라는 단어가 참 직관적인 것 같습니다.
2. 모든 객체가 공통으로 갖게 될 부분이 객체 생성을 매번 할때마다 메모리에 할당된다는 것은 비효율적입니다.
=> 사실 다른 객체지향 언어로 프로그래밍 할 떄에는 그냥 생각없이 넘어갔던 것이었는데, 이 강의에서 새삼 놀라고 이 점에 대해 고민하게 되었습니다.
다른 언어들은 이 문제점을 어떻게 극복하는 것일까요..?? 동작방법이 다른걸까요.. 저는 지식이 얕아서 잘 모르겠습니다ㅎㅎ;
3. 속성/메소드를 프로토타입을 이용하여 바깥에 빼둠으로서, 객체가 생성될때마다 공통부분이 메모리에 중복되어 쌓이는 일이 없도록 할 수 있습니다.
=> 그렇지만, 선생님께서 말씀하신대로 데이터 같은 속성들은 아무래도 객체가 갖고 있는 것이 객체지향 프로그래밍에 더 맞는 것 같습니다...
1억개의 생성자 함수 안에 메소드 또는 속성을 정의할 경우 성능저하를 불러올 수 있다 하지만 프로토타입을 쓰게되면서 메모리절약과 함께 재사용을 할 수 있다
컨스트럭터를 이용해 데이터와 메소드를 정의할 때 데이터는 주로 컨스트럭터 안에 저장, 메소드는 프로토타입을 이용해 따로 생성한다. 이유는 새로운 객체를 생성할 때마다 객체 자체에 저장 되어 있지 않은 메소드를 정의하지 않음으로써 속도를 빠르게 하고 메모리를 아낄 수 있고, 또한 모든 객체의 공통된 메소드 수정이 용이하기 때문이다.
메소드를 호출할 때, 자바스크립트는 객체내에 있는 메소드를 먼저 찾고, 객체 내에 호출한 메소드가 없을 때 비로소 프로토타입으로 정의한 메소드를 찾는다.
정리.
(prop, value, func, [" "])은유적 표현입니다.
실제 코드는 저래쓰심안되요.
1. 인스턴스가 가져야 할 고유 Data는 생성자 내부에서
this.["prop"] = value; 로 초기화 할것.
2. 그 클래스의 모든 인스턴스가 가져야할 공통분모는
클래스.prototype.["prop & func"] = value & func(){};
이렇게 값이든 함수든 공통 맴버로 사용.
프로토타입 하나에 수많은 객체들을 담기때문에 sum의 함수를 반복적으로 불러올필요가 없고, 이는 메모리를 많이 잡아먹지 않음으로써 성능저하를 방지할수 있습니다
강의 복습: (강의 내에서 정의되었던) Person 생성자를 이용하여 이미 일억개의 객체(예를 들면 User)를 생성한 직후, sum함수의 return 값이 잘못되었다는 것을 깨달았다고 가정해봅니다.
이 때 Person 생성자 내의 sum 함수의 return값을 수정한들, 이미 생성된 객체들의 sum함수는 변경되지 않습니다. 앞으로 생성될 객체들에서부터 적용되겠죠. 그럼 이미 생성된 객체들에 대해서는 모두 직접 변경해주어야합니다. (못할짓이죠ㅎ)
그렇기 때문에 prototype을 사용하게 됩니다. 생성자로부터 분리하여, 함수를 매번 생성자 내에서 정의하면서 발생했던 메모리 및 성능 비효율성을 해결하고, 함수 자체의 수정도 자유로워진 것이죠. Prototype의 뜻은 '원형'이므로 각 객체가 자기 자신의 함수를 커스터마이징하지 않는 한, 모든 객체가 동일하게 사용할 수 있는 기본 형식 같은 의미가 아닐까 생각합니다.
이 때 Person 생성자 내의 sum 함수의 return값을 수정한들, "이미 생성된 객체들의 sum함수는 변경되지 않습니다." 앞으로 생성될 객체들에서부터 적용되겠죠. 그럼 이미 생성된 객체들에 대해서는 모두 직접 변경해주어야합니다.
-> Person 생성자 내의 sum 함수를 수정하면 생성된 객체들의 sum 함수가 변경되기 때문에 출력값이 변경되는 거 아닌가요? 제가 무언가 잘못 생각하고 있는 게 있다면 지적 부탁드립니다.
동작순서 : lee 객체 자신이 sum이라는 함수를 가지고 있지 않으면. lee 객체의 생성자인 Person의 prototype에 sum이 정의되어 있는지를 찾아본다.
- JS에서 프로토타입이란?
: JS에선 '원형'이란 의미로서 함수 등의 객체에게 'DNA' 같은 역할을 하는 것이다.
자바 같은 데선 클래스를 통해 상속을 구현한 것과 달리, JS에선 이 프로토타입(prototype)이란 속성을 통해 상속을 구현하도록 되어 있다. 최상위 조상 객체부터 최하단의 자손 객체에 이르기까지 prototype속성을 통해 연결시킨 '상속관계'를 만듬으로써 'prototype chain'모양을 갖춘 상속관계가 완성되어진다.
- 프로토타입을 사용하지않고 생성자 함수 안에서 메소드나 속성을 정의하게 되면 어떤 비효율이 발생하게 되는가?
: 매 객체가 생성될 때 마다 해당 메소드/속성이 '반복적으로' 계속 생겨나게 되고, 이는 동일한 내용이 메모리를 중복적으로 차지하여 '낭비'가 발생하게 된다. 객체 숫자가 많아질 수록 이는 더욱 시스템에 부담이 된다.
- 그 비효율을 프로토타입을 통해 어떻게 극복하게 되었는가?
: 함수 안에 '중복적인 속성/메소드'를 정의해놓지 않고, 해당 함수의 원형(prototype)에 만들어 박아놓으면 그 함수로부터 파생된 모든 객체들은 해당 속성/메소드를 모두 접근해 이용할 수 있게 된다. 이를 통해 중복적인 내용이 반복생성되는 것을 막고 메모리의 낭비를 막을 수 있다.
감사합니다 선생님
사실 프로토타입을 사용하기보단 Person()에 sum()을 추가하면 되지않을까 ?
했는데 코드를 붙였다 분리했다하는 프로토타입이 부품역할도 될수 있고 코드가 조잡한게 깔끔해주셔서 사용하는건가요..? 맞나요?..
제가 이해한 바로는 이런거같아요.
사천요리 전문 중국집이 있어요. 그 가게에서는 탕수육을 시켜도 기본으로 사천 탕수육이 나오고, 짜장면을 시켜도 사천 짜장면이 나오죠.
사천화 시킨다 라는 함수가 프로토타입에 정의되어있기때문이죠.
매운걸 못먹는 사람은 별도로 ‘안맵게 해주세요’ 라고 주문할테고, 주방장은 그 인스턴스의 음식만 별도로 처리하겠죠.
만약 프로토타입에 ‘사천화 시킨다’ 라는 함수가 정의되어있지않다면 모든 주문마다 주방장과 서버, 손님은
“맵게?” > “손님 맵게해드릴까요?” > “음 얼마나 매워요?” > “신라면보다 매워요” > “네 그럼 맵게해주세요” > “주방장님 맵게요”
이 과정을 겪어야하고, 그건 너무 비효율적이기때문에 프로토타입을 따로 정의한게 아닐까요?
Prototype은 생성자 함수로 찍어낸 객체 안에 들어갈 메서드의 기본 제작 청사진이라고 할 수 있다. 객체 공장에서 객체를 찍어내는 기계에게 별도로 새로운 형태의 객체를 주문 제작하지 않는 이상 기계는 Prototype대로 객체를 찍어낸다.
Prototype 없이 생성자 함수를 호출할 때마다 새로 메서드를 만들면 메모리를 낭비하게 된다. 참고할 기본 형태가 없어서 객체 찍는 기계가 힘든 것이다.
Prototype은 객체 찍는 기계에게 별도의 명령을 내리지 않는 한 그대로 만들면 되는 설계도를 제공한다. 기계도 덜 힘들고, 프로그래머도 코드를 줄일 수 있다.
안녕하세요 이고잉 선생님! 이해가 안되는 부분이 있어 질문드립니다. kim.sum() 의 경우 30이라는 값이 나오는데 kim.__proto__.sum() 은 NaN이 나오는 이유가 뭘까요?
프로토 타입 속성을 이용해서 메소드를 객체 생성자 함수 내에 두지 않고 분리할 수 있습니다.
이렇게 하면 객체가 생성될 때마다 메소드를 호출하지 않고, 해당 메소드가 필요한 경우에만 호출하여 사용할 수 있으니 메모리 성능이 높아진다고 이해했어요.
추가적으로, 생성된 특정 객체의 속성을 직접 지정하는 경우는 프로토타입의 속성보다 우선한다고 보았습니다.
예제로 만들어주신 코드에서는 kim.sum 선언문이 Person.prototype.sum 선언문이 보다 아래에 있기 때문에 우선한 것이 아닌가 했는데 직접 순서를 바꿔봐도 kim.sum이 우선되어 적용되네요~
메모리 장점 말고는 필요성을 못느꼈다... 객체내용이 홀딩 되어 있어야 하는 상황인가 더공부해봐야겠네
생성자 함수로 생성되는 모든 객체의 인스턴스가 공유할 원형을 담아내는 객체로 메모리의 효율과 성능의 이점을 가져올 수 있고, 특별하게 메소드를 다르게 해야 하는 경우에는 그 객체에 맞는 메소드를 재정의 할 수 있다. prototype이 아닌 기존의 방식을 사용한다면 같은 객체를 무수히 많이 생성한다고 할 때, 성능과 메모리에 좋지 않아 생산성이 떨어진다.
전역 변수 처럼 전역 함수를 쓰기 위해선 prototype이 필요한 개념이 맞나요?
Date 라는 함수는 인자로 날짜를 주면 분명 getDate 나 getMonth 같은 메서드로 마치 인자 처럼 활용하는데 아무리 봐도 프로토타입이나 생성자 객체 내에 어떠한 프로퍼티로도 주어지지 않길레 도대체 왜 이런지 궁금하여 Date 라는 함수의 native code를 볼 방법이 없을까 싶어 검색을 해보니 c 나 c++언어로 만들어져 있다고 하네요. 그래서 포기했습니다.
자바스크립트의 native code는 c 나 c++언어로 만들어진다고 합니다.
프로토타입 : 인스턴스가 사용할 수 있는 메서드를 저장하는 곳
Person.prototype.sum 을 언어로 풀이해보면 'Person 함수내의 sum 메소드의 원형을 정한다.' 정도로 해석하면 될까요?
이상하네.. 영상 초반에 kim과 lee의 메소드인 sum의 리턴값을 바꿀때 굳이 밖으로 꺼내지 않고 person 이라는 생상자 함수 안에 있는 this.sum의 리턴값을 수정해도 다 적용이 되는데 이렇게 되면 굳이 1억번씩 반복하지 않아도 되지 않을까요?