js
다음 두 가지 상속 방법이 일반적으로 사용됩니다.
프로토타입 체인 상속(객체 간 상속)
클래식 상속(생성자 간 상속)
js
은 java
처럼 진정한 객체지향 언어가 아니기 때문에 js
은 객체 기반이고 클래스가 없습니다. 개념. 따라서 상속을 구현하려면 js
의 프로토타입 메커니즘을 사용하거나 apply
및 call
메서드를 사용하여
을 구현하면 됩니다. 객체 지향 언어에서는 类
을 사용하여 자동 정의 개체를 만듭니다. 그런데 js
에 있는 모든 것은 객체인데 어떻게 사용자 정의 객체를 만들 수 있나요? 이를 위해서는 js
의 프로토타입을 사용해야 합니다.
간단히 prototype
를 템플릿으로 간주할 수 있으며 새로 생성된 사용자 정의 개체는 모두 이 템플릿(prototype
)의 복사본입니다(실제로, 복사본이 아니라 링크이지만 이 링크는 보이지 않습니다. 새로 인스턴스화된 객체 내부에는 프로토타입 객체를 가리키는 보이지 않는 __Proto__
포인터가 있습니다.
js
생성자와 프로토타입을 통해 구현 클래스의 기능을 시뮬레이션할 수 있습니다. 게다가 js
클래스 상속 구현도 프로토타입 체인에 의존합니다.
类式继承
은 하위 유형 생성자 내부에서 상위 유형 생성자를 호출하는 것입니다.
엄격한 클래스 상속은 흔하지 않으며 일반적으로 조합하여 사용됩니다.
function Super(){ this.colors=["red","blue"]; } function Sub(){ Super.call(this); }
原型式继承
는 기존 객체의 도움으로 하위 클래스의 프로토타입을 가리키는 새 객체를 생성하는 것입니다. 상위 클래스 A 클래스는 상위 클래스의 프로토타입 체인에 합류하는 것과 동일합니다
하위 클래스가 상위 클래스의 속성(메소드 포함)을 상속하려면 먼저 생성자를 정의해야 합니다. 그런 다음 상위 클래스의 새 인스턴스를 생성자의 프로토타입에 할당합니다. 코드는 다음과 같습니다:
<script> function Parent(){ this.name = 'mike'; } function Child(){ this.age = 12; } Child.prototype = new Parent();//Child继承Parent,通过原型,形成链条 var test = new Child(); alert(test.age); alert(test.name);//得到被继承的属性 //继续原型链继承 function Brother(){ //brother构造 this.weight = 60; } Brother.prototype = new Child();//继续原型链继承 var brother = new Brother(); alert(brother.name);//继承了Parent和Child,弹出mike alert(brother.age);//弹出12 </script>
위의 프로토타입 체인 상속에는 여전히 하나의 누락된 링크가 있습니다. 바로 Object
입니다. 모든 생성자는 Object
에서 상속됩니다. 상속Object
은 자동으로 완료되므로 수동으로 상속할 필요가 없습니다. 그렇다면 이들의 소속은 무엇입니까?
프로토타입과 인스턴스 간의 관계는 두 가지 방법으로 결정할 수 있습니다. 연산자 instanceof
및 isPrototypeof()
메소드:
alert(brother instanceof Object)//true alert(test instanceof Brother);//false,test 是brother的超类 alert(brother instanceof Child);//true alert(brother instanceof Parent);//true
프로토타입 체인에 등장한 프로토타입인 만큼 프로토타입 체인에서 파생된 인스턴스의 프로토타입이라고 할 수 있습니다. , isPrototypeof()
메소드는 true
도 반환합니다. js
에서는 상속된 함수를 슈퍼 유형(상위 클래스, 기본 클래스도 허용됨)이라고 하며, 상속된 함수를 하위 유형이라고 합니다. (하위 클래스, 파생 클래스). 프로토타입 상속 사용에는 두 가지 주요 문제가 있습니다.
첫째, 프로토타입을 문자 그대로 다시 작성하면 참조 유형의 프로토타입을 사용하여 관계가 깨지고 하위 유형이 상위 유형에 매개변수를 전달할 수 없습니다.
유사 클래스는 참조 공유 문제와 슈퍼 유형의 매개변수 전달 불가 문제를 해결합니다.
<script> function Parent(age){ this.name = ['mike','jack','smith']; this.age = age; } function Child(age){ Parent.call(this,age); } var test = new Child(21); alert(test.age);//21 alert(test.name);//mike,jack,smith test.name.push('bill'); alert(test.name);//mike,jack,smith,bill </script>
차용 생성자를 사용하면 방금 언급한 두 가지 문제가 해결되지만 프로토타입이 없으면 재사용이 불가능하므로 결합 상속이라고 하는 原型链+借用构造函数
패턴이 필요합니다.
<script> function Parent(age){ this.name = ['mike','jack','smith']; this.age = age; } Parent.prototype.run = function () { return this.name + ' are both' + this.age; }; function Child(age){ Parent.call(this,age);//对象冒充,给超类型传参 } Child.prototype = new Parent();//原型链继承 var test = new Child(21);//写new Parent(21)也行 alert(test.run());//mike,jack,smith are both21 </script>
결합 상속은 일반적으로 사용되는 상속 방법으로, 프로토타입 체인을 사용하여 프로토타입 속성과 메서드를 상속하고 생성자를 빌려 인스턴스 속성을 상속하는 것입니다. 이러한 방식으로 함수 재사용은 프로토타입에 메서드를 정의하여 달성되며 각 인스턴스는 고유한 속성을 갖도록 보장됩니다.
call()
사용법: 개체의 메서드를 호출하여 현재 개체를 다른 개체로 바꿉니다.
call([thisObj[,arg1[, arg2[, [,.argN]]]]])
이런 종류의 상속은 사용자 지정 유형을 만들지 않고 프로토타입을 사용하여 기존 객체를 기반으로 새 객체를 생성하는 것을 原型式继承
<script> function obj(o){ function F(){} F.prototype = o; return new F(); } var box = { name : 'trigkit4', arr : ['brother','sister','baba'] }; var b1 = obj(box); alert(b1.name);//trigkit4 b1.name = 'mike'; alert(b1.name);//mike alert(b1.arr);//brother,sister,baba b1.arr.push('parents'); alert(b1.arr);//brother,sister,baba,parents var b2 = obj(box); alert(b2.name);//trigkit4 alert(b2.arr);//brother,sister,baba,parents </script>
프로토타입 상속이라고 합니다. obj()
함수 내에 임시 생성자를 생성한 다음 들어오는 객체를 이 생성자의 프로토타입으로 사용하고 마지막으로 이 임시 유형의 새 인스턴스를 반환합니다.
이 상속 방법은 프로토타입 + 팩토리 패턴을 결합하여 생성 프로세스를 캡슐화합니다.
<script> function create(o){ var f= obj(o); f.run = function () { return this.arr;//同样,会共享引用 }; return f; } </script>
결합 상속은 가장 일반적으로 사용되는 상속 패턴js
이지만 결합 상속의 상위 유형은 한 번 사용하는 동안 두 번 호출됩니다. 다른 하나는 하위 유형 생성자
<script> function Parent(name){ this.name = name; this.arr = ['哥哥','妹妹','父母']; } Parent.prototype.run = function () { return this.name; }; function Child(name,age){ Parent.call(this,age);//第二次调用 this.age = age; } Child.prototype = new Parent();//第一次调用 </script>
내부입니다. 위 코드는 이전 결합 상속이므로 기생 결합 상속은 두 호출의 문제를 해결합니다.
<script> function obj(o){ function F(){} F.prototype = o; return new F(); } function create(parent,test){ var f = obj(parent.prototype);//创建对象 f.constructor = test;//增强对象 } function Parent(name){ this.name = name; this.arr = ['brother','sister','parents']; } Parent.prototype.run = function () { return this.name; }; function Child(name,age){ Parent.call(this,name); this.age =age; } inheritPrototype(Parent,Child);//通过这里实现继承 var test = new Child('trigkit4',21); test.arr.push('nephew'); alert(test.arr);// alert(test.run());//只共享了方法 var test2 = new Child('jack',22); alert(test2.arr);//引用问题解决 </script>
전역 함수 apply
및 call
를 사용하여 함수에서 this
의 지정을 변경할 수 있습니다.
// 定义一个全局函数 function foo() { console.log(this.fruit); } // 定义一个全局变量 var fruit = "apple"; // 自定义一个对象 var pack = { fruit: "orange" }; // 等价于window.foo(); foo.apply(window); // "apple",此时this等于window // 此时foo中的this === pack foo.apply(pack); // "orange"
위 내용은 자바스크립트의 상속방식에 대한 자세한 설명입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!