오프닝
'엄격한' 의미에서 JavaScript는 진정한 객체 지향 언어가 아닙니다. 이렇게 말하는 이유는 일반적으로 약한 유형의 언어인 JavaScript는 Java나 C#과 같은 강한 언어의 상속 방식과 매우 다르기 때문에 기본적으로는 비주류 객체지향 방식이며, 거기에 일반적으로 책에서는 이를 '완전히 객체 지향적이지 않은' 언어라고 설명합니다. 사실 저는 개인적으로 메소드가 중요하지 않고, 객체지향적 사고를 가지고 있느냐가 중요하다고 생각합니다. 소통을 위해 이 글을 썼습니다.
상속 구현을 위해 자바스크립트를 사용해야 하는 이유
초기 PC 시스템의 성능은 정말 만족스럽지 않습니다. 모든 부담은 서버 측에 있고 클라이언트 브라우저는 순전히 장식용입니다. 당시 대중적인 테이블 레이아웃과 전화선 인터넷 액세스와 함께 웹 페이지 탐색이 매우 느렸습니다. 현재 인터넷 시대가 급속도로 발전하고 있으며 개인용 컴퓨터 하드웨어가 크게 향상되었으며 클라이언트 브라우저의 성능도 매우 실망스럽습니다. 웹 개발 모델도 조용히 변화하고 있습니다. 서버는 더 이상 이전처럼 "어려워지지" 않습니다. 대신 브라우저는 이러한 방식으로 각 클라이언트에 부담을 분산시켜야 합니다. 기업의 비용 절감은 웹 프런트엔드 개발을 더욱 흥미롭게 만듭니다. 점점 더 많은 프런트엔드 프레임워크가 등장하고 심지어 많은 프런트엔드 MVC 프레임워크도 등장했습니다. 이러한 맥락에서 JavaScript의 역할은 확실히 단순한 확인, 요청 전송, DOM 운영이 아니라 프런트 엔드 라우팅 및 비즈니스 계층과 같은 더 많은 역할을 수행해야 하며 JavaScript는 많은 논리적 작업을 수행해야 합니다. 이는 프런트엔드 데이터(예: 모델)의 추상화를 포함하고 객체 지향적 사고를 통해서만 추상화된 데이터를 잘 처리할 수 있으므로 여기서 상속은 매우 중요합니다.
간단한 필요부터 시작하세요
이제 프론트 데스크에서 name과 age라는 기본 속성을 가진 Person이라는 모델을 추출합니다. 기본적으로 누구나 말할 수 있으므로 말하기 기능은 각 인스턴스의 프로토타입 객체에 배치됩니다. 이제 Man의 경우 Person의 기본 속성을 상속하고 이를 기반으로 고유한 속성을 추가해야 합니다.
function Person (name, age) { this.name = name; this.age = age; } Person.prototype.say = function(){ console.log('hello, my name is ' + this.name); }; function Man() { //my own properties }
다음에서는 몇 가지 주류 상속 방법을 소개합니다.
1. 프로토타입 체인 상속
function Person (name, age) { this.name = name; this.age = age; } Person.prototype.say = function(){ console.log('hello, my name is ' + this.name); }; function Man() { } Man.prototype = new Person('pursue'); var man1 = new Man(); man1.say(); //hello, my name is pursue var man2 = new Man(); console.log(man1.say === man2.say);//true console.log(man1.name === man2.name);//true
이 상속 방법은 매우 직접적입니다. Person의 모든 속성 메서드(인스턴스 및 프로토타입)를 얻기 위해 실제로는 상위 클래스의 인스턴스 new Person('pursue')을 하위 클래스의 프로토타입에 직접 할당합니다. , 하위 클래스 클래스 인스턴스 man1 및 man2 자체는 완전히 비어 있는 객체입니다. 모든 속성과 메서드는 프로토타입 체인에서 찾아야 하므로 발견된 속성과 메서드는 동일합니다.
따라서 프로토타입 체인 상속을 직접 사용하는 것은 비현실적입니다.
2. 생성자 상속을 사용하세요
function Person (name, age) { this.name = name; this.age = age; } Person.prototype.say = function(){ console.log('hello, my name is ' + this.name); }; function Man(name, age) { Person.apply(this, arguments); } //Man.prototype = new Person('pursue'); var man1 = new Man('joe'); var man2 = new Man('david'); console.log(man1.name === man2.name);//false man1.say(); //say is not a function
여기서 하위 클래스는 생성자에서 적용을 사용하여 상위 클래스의 생성자를 호출하므로 적어도 각 인스턴스를 직접 사용하는 것보다 상위 클래스의 속성을 상속하는 것보다 훨씬 낫습니다. 자체 공유 리소스가 있지만 이 메서드는 상위 클래스의 인스턴스 속성만 상속할 수 있으므로 say 메서드를 찾을 수 없습니다. 상위 클래스의 모든 속성과 메서드를 상속하려면 프로토타입 체인을 수정해야 합니다. 따라서 결합 상속 방법을 도입합니다.
3. 조합 상속
function Person (name, age) { this.name = name; this.age = age; } Person.prototype.say = function(){ console.log('hello, my name is ' + this.name); }; function Man(name, age) { Person.apply(this, arguments); } Man.prototype = new Person(); var man1 = new Man('joe'); var man2 = new Man('david'); console.log(man1.name === man2.name);//false console.log(man1.say === man2.say);//true man1.say(); //hello, my name is joe
man1과 man2의 인스턴스 속성은 실제로 프로토타입 속성을 재정의하지만 프로토타입의 say 메서드를 재정의하지 않는다는 점에 유의해야 합니다. 따라서 여기서는 man1.say === man2입니다. .say는 여전히 true를 반환하므로 모든 인스턴스에 공통되는 프로토타입 속성을 재정의하지 않도록 주의하세요.
4. 기생 조합 상속
솔직히 다음 형식의 이름은 잘 모르겠지만, 실제로 가장 인기 있고 고전적인 JavaScript 상속 방법입니다. 실제로 프로토타입 객체의 구조만 이해하면 됩니다.
function Person (name, age) { this.name = name; this.age = age; } Person.prototype.say = function(){ console.log('hello, my name is ' + this.name); }; function Man(name, age) { Person.apply(this, arguments); } Man.prototype = Object.create(Person.prototype);//a. Man.prototype.constructor = Man;//b. var man1 = new Man('pursue'); var man2 = new Man('joe'); console.log(man1.say == man2.say); console.log(man1.name == man2.name);
사실 기생 조합 상속과 위 조합 상속의 차이점은 서브클래스(a. 및 b.)의 프로토타입 객체를 구성하는 방식에만 있습니다. 여기서는 Object.creat(obj) 메서드를 사용합니다. 들어오는 obj를 처리합니다. 객체는 다음과 유사하게 단순 복사됩니다.
function create(obj){ function T(){}; T.prototype = obj; return new T(); }
따라서 a.는 일반적인 결합 상속(예: Man.prototype = new Person())처럼 하위 클래스의 프로토타입을 직접 복사하는 대신 하위 클래스의 프로토타입 객체를 상위 클래스의 프로토타입 객체와 잘 연결합니다. ;) 이것은 단지 매우 폭력적인 속성 덮어쓰기입니다. 기생 조합 상속 방법은 인스턴스 속성과 프로토타입 속성을 별도로 상속하므로 구현이 더 합리적입니다.
참고: 코드 b는 instanceof의 결과를 변경하지 않지만 생성자가 필요한 시나리오에서는 더 엄격합니다.
위의 Javascript의 여러 상속 방법에 대한 비교 분석은 모두 편집자가 공유한 내용이므로 참고가 되기를 바라며, Script Home을 지원해 주시길 바랍니다.