`(1)类的创建,
然后在构造函数中的prototype中增加属性和方法,构造函数中的普通函数会直接执行
特别要注意在构造函数的prototype中书写的方法是在实例化对象的__proto__=构造函数.prototype 所以可以直接调用
所有实例化对象通过原型链的方式可以共享构造函数prototype中的方法,
构造函数中的其他语句依然是像普通语句一样顺序执行, this一定要配合new来使用,顺序执行,开辟了一个空间,让构造函数中的this指向新开辟的空间,顺序执行构造函数,然后给新的空间添加方法和属性.`
function Animal(name){
this.name=name
this.giao
this.sex=function () {
console.log(1);
}
this.size=()=>{
console.log(12);
}
}
// Animal()//这样子相当于在执行语句的时候给window添加方法和属性
// console.log(size());
Animal.prototype.giao=function(){
return console.log('giao');
}
var x= new Animal()
x.__proto__=Animal.prototype x.__protp__constructor就是Animal.prototype中的constructor 指向这个函数本身
prototype={
1.自己添加的方法或属性
2.constructor指向函数本身
3.__proto__ 指向上一级构造函数的prototype
}
1.原型链继承
function Cat(){
}
Cat.prototype=new Animal()
var cat =new Cat()
cat= {
__proto__=Cat.prototype= {
name,
sex,
size,
__proto__=Animal.prototype={
giao,
constructor,
__proto__=Object.prototype={
call,
bind,
apply,
constructor,
__proto__:null
}
}
}
}
console.log(cat.__proto__.__proto__.giao())
2.构造继承 :使用父类的构造函数来增强子类实例,等于是赋值父类的实例属性给子类
function Cat(name){
Animal.call(this);
this.name=name
}
var cat= new Cat()
cat ={
name,
size,
sex,
__proto__=Cat.prototype={
constructor: Cat,
__proto__=Object.prototype={
call,
bind,
apply,
constructor,
__proto__:null
}
}
}
优点:可以多继承,缺点:不能继承父类构造函数的原型对象,所以破坏了原型链继承的完整性
(3)组合继承:相当于构造函数和原型链继承的组合体,通过调用父类的狗奥,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数的复用
function Cat(name){
Animal.call(this)
this.name=name
}
Cat.prototype=new Animal()
Cat.prototype.constructor=Cat
var cat=new Cat()
cat ={
name,
sex,
size,
__proto__=Cat.prototype={
name,size,sex,
constructor:Cat(),
__proto__=Object.prototype
}
}
console.log(cat);
特点:既可以实现多继承,也可以继承父类的原型对象中的数据,但是会在__proto__中也生成一份实例,造成了内存的浪费
var cat=new Cat()
console.log(cat);
(4)原型式继承
基本想法:借助原型可以基于已有的对象创建新对象,同时还不必须因此创建自定义的类型,
function object(obj){
function F(){
F.prototype=obj
return new F()
}
}
var cat = new Cat()
我觉得没啥用,父类的引用属性会被所有子类实例共享,因为父类的引用的浅赋值
(4)寄生组合继承,使用原型式继承获得一个目标对象的浅复制,然后增强这个浅复制的能力
本质上和原型式继承没有任何区别,只不过可以多添加一些方法和属性
function createAnnther(obj){
var clone=object(obj)
clone.color=function(){
console.log('giao');
}
return clone
}
最完美的继承
原型式方法
function object(obj){
function F(){}
F.prototype=obj
return new F() //返回的式F的实例对象 ,实例对象的__proto__指向的是obj
}
//寄生式方法
function inherit(theFatherFunction,theSonFunction){
var prototype=object(theFatherFunction.prototype)
console.log(prototype);
//复制了父亲的原型方法,得到拥有__proto__指向父亲prototype的实例对象
prototype.constructor=theSonFunction// 改变constructor的指向,指向儿子构造函数
theSonFunction.prototype=prototype //得到了父亲方法的完美儿子构造函数
}
function Parent(name){
this.name=name
this.height=function(){
console.log('giaogiao');
}
}
Parent.prototype.getName=function(){
console.log(this.name);
}
var xx=new Parent()
console.log(xx);
function Child(name,age){
Parent.call(this,name)
this.age=age
}
inherit(Parent,Child)
var son=new Child()
console.log(son);
**直观来看,完美的继承,
其一: 要实现子类构造函数要继承父类构造函数的this指向的属性和方法, 而借用call来构造继承,可以满足这一需求,且还可以多继承
其二: 要实现子类构造函数要继承父类构造函数的原型对象中的方法,而用此处用原型链继承,有问题,不能实现多继承,且造成了,内存狼内,而__proto__=prototype中的constructor会任然指向父类构造函数,所以此处用原型式继承,可以继承父类的原型对象,运用寄生的手段改变constructot的指向,可以实现父类原型对象的完美继承
其三:还有不完善的地方,没有实现多父类原型方法的继承,可以用过代码修改**
(7)
// es6中的class继承
// es6引入class关键字,class可以通过extends关键字实现继承,还可以以通过static关键字定义静态类方法,这比es5的通过修改原型链实现继承,先将父类实例对象的属性和方法,加到this上卖
class Person {
constructor(name,age){
this.name=name
this.age=age
}
showName(){
console.log(this.name);
}
}
class Child extends Person{
constructor(name,age,salary) {
super(name,age)//通过super调用父类的构造方法
this.salary=salary
}
showGiao(){
console.log('giao');
}
}
var s1= new Child('giao1',23,10000)
console.log(s1);