자바스크립트도 객체지향 언어이지만 클래스 기반 언어가 아닌 프로토타입 기반 언어입니다. Javascript에서는 클래스와 객체 사이에 큰 차이가 없는 것 같습니다.
프로토타입이란 무엇인가요?
함수로 정의된 객체에는 프로토타입 속성이 있고, 프로토타입 속성은 프로토타입 객체를 가리킵니다. 프로토타입 속성과 프로토타입 객체는 서로 다른 것이므로 차이점에 주의하세요. 프로토타입 객체에는 또 다른 생성자 속성이 있습니다. 이 생성자 속성도 생성자 객체를 가리키며, 이 생성자 객체는 바로 함수 자체입니다. 많이 복잡하지 않나요? 의사 코드로 표현하면 다음과 같습니다.
var function{ prototype:prototype{ constructor:constructor == function } }
아직 이해가 안 되시나요? 사진을 보세요:
프로토타입의 역할:
이 프로토타입의 역할은 정확히 무엇인가요? 아래 예를 살펴보세요.
function jb51(){ } jb51.prototype.name = "a"; var test = new jb51(); alert(test.name)//"a";
이상하네요 당연히 테스트용으로 name 속성이 설정되어 있지 않은데 왜 값이 있는 걸까요?
이것은 프로토타입의 기여입니다. uw3c의 프로토타입 속성에 있는 이름 object는 uw3c가 새 생성자에 의해 생성된 후 객체 테스트의 속성으로 상속됩니다. 다음 읽기:
var name = "js"; function jb51(name){ alert(this.name);//"css" } jb51.prototype.name = "css"; var test = new jb51(); test()
alert 값이 "js"가 아닌 이유는 무엇인가요? 대략적인 과정은 다음과 같습니다.
var test={}; uw3c.call(test);
첫 번째 단계는 새 개체를 만드는 것(테스트)입니다.
두 번째 단계는 객체(테스트)의 내장 프로토타입 객체를 생성자의 프로토타입 속성이 참조하는 프로토타입 객체(즉, uw3c)로 설정하는 것입니다.
세 번째 단계는 객체(테스트)를 이 매개변수로 사용하여 생성자(즉, uw3c)를 호출하여 멤버 설정 등의 초기화 작업을 완료하는 것입니다.
두 번째 단계에서 새로운 용어가 등장했는데, 이는 내장 프로토타입 객체입니다. 이 새로운 용어는 프로토타입 객체와 구별하기 위해 inobj라고 부르며, inobj는 다음을 가리킵니다. uw3c 함수의 프로토타입 객체. uw3c의 프로토타입 객체에 나타나는 모든 속성이나 함수는 테스트 객체에서 직접 사용될 수 있습니다. 이것이 JS의 프로토타입 상속입니다.
일반적으로 다음과 같은 개체를 만듭니다.
function person(name){ this.sayHi = function(){ alert('hi ' + this.name); } this.name = name; } var p = new person("dan"); p.sayHi();
위에서 new 키워드를 사용하여 객체를 통해 객체 인스턴스를 생성합니다(함수도 특수 객체입니다).
클래스 기반 언어에서는 일반적으로 속성이나 필드가 클래스에 미리 정의되어 있지만 Javascript에서는 객체가 생성된 후에 클래스에 필드를 추가할 수 있습니다.
function animal(){} var cat = new animal(); cat.color = "green";
위의 색상 필드는 현재 고양이 인스턴스에만 속합니다.
나중에 추가된 필드의 경우 모든 동물 인스턴스에 해당 필드를 포함시키려면 어떻게 해야 합니까?
--使用Prototype function animal(){} animal.prototype.color= "green"; var cat = new animal(); var dog = new animal(); console.log(cat.color);//green console.log(dog.color);//green
Prototype을 통해 필드뿐만 아니라 메소드도 추가할 수 있습니다.
function animal(){} animal.prototype.color= "green"; var cat = new animal(); var dog = new animal(); console.log(cat.color);//green console.log(dog.color);//green animal.prototype.run = funciton(){ console.log("run"); } dog.run();
Prototype 속성을 통해 객체를 생성한 후 객체의 동작을 변경할 수도 있다는 것이 밝혀졌습니다.
예를 들어 배열이라는 특수 개체에 메서드를 추가할 수 있습니다.
Array.prototype.remove = function(elem){ var index = this.indexof(elem); if(index >= 0){ this.splice(index, 1); } } var arr = [1, 2, 3] ; arr.remove(2);
프로토타입을 통해 객체의 속성이나 메서드를 정의하는 것 외에도 객체의 생성자를 통해 클래스 속성이나 메서드를 정의할 수도 있습니다.
function animal(){ this.color = "green"; this.run = function(){ console.log("run"); } } var mouse = new animal(); mouse.run();
위 접근 방식을 사용하면 모든 동물 인스턴스가 모든 필드와 메서드를 공유할 수도 있습니다. 그리고 또 다른 장점은 생성자에서 클래스의 지역 변수를 사용할 수 있다는 것입니다.
function animal(){ var runAlready = false; this.color = "green"; this.run = funciton(){ if(!runAlreadh){ console.log("start running"); } else { console.log("already running") } } }
사실 더 실용적인 접근 방식은 프로토타입과 결합된 생성자를 통해 클래스의 필드와 동작을 정의하는 것입니다.
function animal(){ var runAlready = false; this.run = function(){ if(!runAlready){ console.log('i am running'); } else { console.log("i am already running"); } } } animal.prototype.color = ''; animal.prototype.hide = funciton(){ console.log(""); } var horse = new animal(); horse.run(); horse.hide();
Prototype을 사용하면 객체를 생성한 후 객체나 클래스의 동작을 변경할 수 있으며, 프로토타입 속성을 통해 추가된 이러한 필드나 메서드는 모든 객체 인스턴스에서 공유됩니다.