JavaScript의 상속은 매우 이상합니다. 인터페이스 상속을 구현할 수 없으며 프로토 타입 상속에만 의존 할 수 있습니다.
프로토 타입 체인
프로토 타입은 물체입니다. 생성자를 통해 생성 된 인스턴스는 프로토 타입의 특성 및 방법을 얻기 위해 프로토 타입에 대한 포인터를 갖습니다. 이러한 방식으로, 인스턴스 객체는 생성자의 속성 메소드와 프로토 타입의 속성 메소드를 갖는 다음이 인스턴스에 상속되어야하는 생성자의 프로토 타입을 가리므로 인스턴스의 모든 속성 메소드가 상속 될 수 있습니다.
다음 데모 코드를 참조하십시오.
// 수퍼 클래스를 선언하고 생성자 및 프로토 타입을 통해 관련 속성 및 메소드를 추가하십시오. super () {this.property = true;} super.getSuperValue = function () {return this.property;}; // 생성자 기능 하위 유형 () {this.subproperty = false; 슈퍼 클래스 및 모든 것을 수퍼 클래스 서브 타입 .prototype = new Super (); subtype.prototype.constructor = subtype; subtype.prototype.getSubvalue = function () {return.subproperty;}; // 슈퍼 클래스 메소드 및 varclass (new subte)를 테스트할지 여부를 테스트할지 여부; console.log (instance.getSuperValue ());모든 함수의 기본 프로토 타입은 객체의 인스턴스이므로 기본 프로토 타입에는 Object.Prototype에 대한 내부 포인터가 포함됩니다.
인스턴스와 isprototypof를 사용하여 프로토 타입과 인스턴스 사이의 관계를 결정합니다.
Object의 인스턴스 인스턴스; object.prototype.isprototypof (인스턴스);
프로토 타입 체인을 사용할 때는 메소드를주의 깊게 정의해야합니다. 서브 클래스는 SuperType의 메소드 또는 확장을 다시 작성해야하며 프로토 타입을 대체하는 명령문 뒤에 배치하여 적용 할 수 있습니다. 또한 프로토 타입 체인을 통해 상속 할 때 객체 리터럴을 사용하여 프로토 타입 메소드를 만들 수 없으며 프로토 타입 체인을 무시할 수 없습니다.
...... subtype.prototype = new super (); subtype.prototype = {....};이것은 포인터를 대체하여 새 객체를 가리키고 프로토 타입 체인을 다시 작성합니다.
프로토 타입 체인의 상속 방법은 결함이 있으며 두 가지 주요 문제가 있습니다.
1. 참조 유형 값을 포함하는 프로토 타입에서 모든 인스턴스에서 공유됩니다.
이전 기사에서 언급했듯이, 참조 유형 값을 포함하는 프로토 타입 속성은 모든 인스턴스에서 공유됩니다. 하나의 인스턴스가 수정되고 다른 인스턴스는 그에 따라 변경됩니다. 따라서 속성은 생성자에 정의되어야합니다. 프로토 타입 체인이 상속되는 경우, 슈퍼 클래스의 속성이 생성자 또는 프로토 타입에 정의 되든 모두 인스턴스 객체가되고 서브 클래스에 의해 상속되므로 서브 클래스의 인스턴스에 영향을 미칩니다.
2. 하위 유형의 인스턴스를 생성 할 때 매개 변수를 슈퍼 타입 생성자로 전달할 수 없습니다.
프로토 타입 체인의 상속은 서브 클래스 프로토 타입을 슈퍼 클래스의 인스턴스에 직접 지적하며, 이때 매개 변수를 슈퍼 클래스로 전달할 수 있습니다. 그러나, 서브 클래스가 인스턴스를 생성 할 때, 매개 변수를 서브 클래스의 생성자에게만 전달할 수 있지만 슈퍼 클래스의 생성자에게는 안됩니다.
따라서 실제 응용 분야에서 프로토 타입 체인은 거의 사용되지 않습니다.
일부 관련 코드 관행
프로토 타입 속성을 식별하십시오
함수 HASPROTOTYPEPROPERTY (Object, Name) {Object &&! Object.HasOwnProperty (이름);}의 리턴 이름생성자에서 프로토 타입 객체 사용
기능인 (이름) {this.name = name;} person.prototype = {생성자 : person, sayname : function () {console.log (this.name); }, toString : function () {}}; var person1 = new Person ( 'nicholas'); var person2 = new Person ( 'greg); console.log (person1 instances); // trueconsole.log (person1.constructor === person); // trueconsole.log (person1.constructor === person); // trueconsole.log (person1.constructor === 객체); // falseconsole.log (person2 인스턴스의 인스턴스); // trueconsole.log (person2.constructor === person); // trueconsole.log (person2.constructor === 객체); // 거짓객체 상속
var person1 = {name : 'nicholas', sayname : function () {console.log (this.name); }}; var person2 = object.create (person1, {name : {configurable : true, enumerable : true, value : 'greg', writable : true}}); person1.sayname (); // nicholasperson2.sayname (); // gregconsole.log (person1.hasownproperty ( 'sayname')); // trueconsole.log (person1.ispropertyof (person2)); // trueconsole.log (person2.hasownproperty ( 'sayname')); // 거짓모듈 모드
var person = (function () {var age = 25; function getage () {return age;} function growolder () {age ++;} return {이름 : 'nicholas', getage : getage, growolder};} ();범위 생성자
기능인 (이름) {this.name = name;} person.prototype.sayname = function () {console.log (this.name);}; var person1 = person ( 'nicholas'); console.log (person1 인스턴스); // falseconsole.log (typeof person1); // undefinedConsole.Log (이름); // 니콜라스