1.原型和原型链
1.什么是原型和原型链?
原型也叫原型对象,任何一个函数都有prototype属性,这个属性是声明函数时js自动加的,prototype初始时时一个空对象。这个对象就叫原型对象。
原型链:每个对象都有_proto_属性,这个指向其构造函数的原型对象prototype,这个原型对象也有他的_proto_属性指向他的构造函数原型对象。当我们访问一个对象属性的时,先在自身属性中查找,找到返回;如果没有,再沿着__proto__这条链向上查找,形成了原型链。最上层的是Object.prototype 终结于null。
-
为什么要有原型对象?
为了让new生成的实例共享共有的属性,所以设计一个对象专门用来存储对象共享的属性,避免浪费库存。
1、每个对象都有_proto_属性,这个指向其构造函数的原型对象 ;还有一个constructor属性指向构造函数。
2、构造函数原型对象也是一个对象 也有他的_proto_属性和constructor属性 。这样一层一层就形成了原型连。最上层是Object.prototype 终结于null。constructor表明构造关系 终结于Function。
-
原型链。它用来实现原型继承,最上层是 Object.prototype,终结于 null,没有循环
-
构造函数链。它用来表明构造关系,最上层循环终结于 Function
2.构造函数 实例对象 原型对象
来初始化新创建的对象的函数是构造函数,标志性就是被new使用。
通过被构造函数的new出来的对象都叫做实例对象。
任何一个函数都有prototype属性,这个属性是声明函数时js自动加的,prototype初始时时一个空对象。这个对象就叫原型对象。
总结
【1】函数(Function也是函数)是new Function的结果,所以函数可以作为实例对象,其构造函数是Function(),原型对象是Function.prototype。
【2】对象(函数也是对象)是new Object的结果,所以对象可以作为实例对象,其构造函数是Object(),原型对象是Object.prototype
【3】Object.prototype的原型对象是null。
2.继承
www.jb51.net/article/176…
www.jb51.net/article/817…
什么是继承:
一个类获取另一个或者多个类的属性或者方法。继承可以使得子类具有父类的各种方法和属性。以免重复输出很多代码。
1.原型链继承:子类型的原型为父类型的一个实例对象,son.prototype= new Father ();
- 优:父类新增方法子类都能访问,简答好操作。
- 缺: 1、父类使用this声明的属性被所有实例共享。在子类的多个实例中,有一个实例去修改引用数据类型,都会影响到其他子类实例。 2、创建子类实例时,无法向父类构造函数传参,不够灵活。
2.构造函数继承:在子类型构造函数中通用call()调用父类型构造函数,
function Person (){ this.name=name;this.age=age}
function Student(){ Person.call(this,name,age)}
优:解决共享问题,可以传参,多继承
- 缺:
不是父类的实例,是子类的实例。只能继承父类实例的方法,不能继承原型方法。
父类方法无法复用。每次实例化子类,都要执行父类函数。重新声明父类所定义的方法,无法复用。
3.组合继承。通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现函数复用。
- 优点:1、解决原型链继承父类this声明的属性或者方法被共享的问题。2、解决借用构造函数解决不能继承父类prototype对象上的属性/方法问题
- 缺点:
两次调用父类的构造函数,生成了两份实例。
原型链上下文丢失,子类和父类通过prototype声明的属性和方法都存在与子类prototype上。
4. 原型式继承:先创建了一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型,最后返回了这个临时类型的一个新实例。
- 缺点:包含引用类型值的属性始终都会共享,跟原型链继承一样,
5.寄生式继承 (继承过程封装)
跟借用构造函数模式一样,每次创建对象都会创建一遍方法
6.组合寄生(call+寄生式封装)
1、使用借用构造函数来继承父类this声明的属性和方法。2、使用寄生式继承来设置父类prototype为子类prototype的原型来继承父类的属性和方法。
- 优点 1、只调用了父类构造函数一次,节约了性能。 2、避免生成了不必要的属性。 3、使用原型式继承保证了原型链上下文不变,子类的prototype只有子类通过prototype声明的属性和方法,父类的prototype只有父类通过prototype声明的属性和方法。
7.class继承: class关键字,constructor函数调用类的构造方法。 在定义子类用extends继承父类。在constructor函数里面通过super()调用父类的构造方法。
ES6继承的原理跟寄生组合式继承是一样的。优缺点也相仿