三分钟搞定JS继承

一、原型链继承

  • js中无法实现接口继承,依靠原型链来实现继承
基本思想:通过改变prototype的指向形成实例和原型之间的原型链

instanceSub->subType.prototype(instanceSuper)->superType.prototype-> Object.prototype->null

  • 实现步骤
  1. 子对象的原型是父对象的实例 subType.prototype = instanceSuper;subType.prototype=new superType();
  2. 父对象的实例上添加 constructor 属性 指向 subType subType.prototype.constructor = subType;
改变prototype
  1. 动态修改prototype的属性时,会影响所有已经创建和新创建的实例。
  2. 重写prototype,即将prototype赋值为新的对象(对象字面量形式)时,不会影响已经创建的实例,会影响后序创建的实例
			function SuperType() {
				this.property = true;
			}
			SuperType.prototype.getSuperValue = function() {
				return this.property;

			}			
			function subType() {
				this.subproperty = false;

			}
			var instanceSuper = new SuperType();
			subType.prototype = instanceSuper; //子对象的原型是父对象的实例
			//SuperType的实例作为 subType的原型
			subType.prototype.constructor = subType;//添加 constructor 属性 指向 subType
			
			//子对象的原型设置为父对象的实例后,再向子对象原型添加方法	
			subType.prototype.getSubValue = function() {
				return this.subproperty;
			}

			var instanceSub = new subType();
			//子对象能够继承到父对象的方法
			console.log(instanceSub.getSuperValue()); //true
			console.log(instanceSub.getSubValue()); //false
			
原型链的问题
1. 原型链上的属性都是共享的,包含引用类型值(eg:数组类型)的原型属性会被所有实例共享,一改全改
2. 创建子类型的实例时 ,不能向父类型的构造函数中传递参数
3. 解决:使用构造函数解决原型链继承的问题

二、构造函数继承

基本思想:在子对象的构造函数内部调用父类的构造函数
	function SubType(type, price) {
		SuperType.call(this, type);//调用父类构造方法实现继承,同时可以传参	
	}
  • 实例本身不能继承构造函数,实例可以使用构造函数中的属性和方法是由于this
构造函数实现继承的问题
  1. 实例继承自构造函数,而构造函数原型上的属性和方法对实例对象不可见.
  2. 构造函数模式的问题:方法都在构造函数中定义,无法复用

三、原型+构造函数组合继承(常用)

基本思想:使用原型链实现对原型属性和方法的继承,构造函数实现对实例属性的继承
原型+构造函数组合继承的问题: 调用两次超类构造函数。1.创建子类原型 2. 在子类构造内部调用父类构造
			function SuperType(name) {
				this.name=name;
				this.color = ['red', 'green', 'blue'];
				
			}
			
			SuperType.prototype.sayName=function(){
				console.log(this.name);
			}
			
			function SubType(name,age) {
				this.age = age;
				SuperType.call(this,name);//调用父类构造方法实现继承.
			
			}
			
			//继承构造函数原型上的属性和方法
			SubType.prototype=new SuperType();//调用父类构造函数
			SubType.prototype.constructor=SubType;
			SubType.prototype.sayAge=function(){
				console.log(this.age);
			}							
						
			var sub = new SubType('lily',18);
			sub.color.push('black');			
			console.log(sub.color);//["red", "green", "blue", "black"]
			
			var sub2 = new SubType('nacy',12);
			console.log(sub2.color);//["red", "green", "blue"]

四、原型式继承

基本思想:创建一个生成临时构造函数的函数,借助原型,基于已有的对象创建新对象
			function object(o){
				function F(){};//创建临时构造函数
				F.prototype=o;//将临时构造函数的原型设置为超类的对象.
				return new F();//返回临时构造函数的新实例
			}
			var person2=object(person);//则 person2 的原型为person
  • Object.create() 方法规范化了原型式继承,可以使用Object.create()替换object函数

  • Object.create() 是一个系统内置的函数,接收一个参数,一般是对象,返回新创建的对象,并且对象的原型指向传入的参数。
    创建一个空对象,空对象的原型,是传入的参数。

  • Object.create(null); null没有原型,没有prototype属性 ,所以没有toString方法

  • 使用bind函数将函数指向为null后,该函数也没有prototype属性。

原型式继承的问题
  • 引用类型值的属性会被所有实例共享

五、寄生式继承

基本思想:原型式继承+工厂模式(创建一个仅用于封装继承过程的函数,该函数在内部为对象添加属性和方法,然后返回对象)
寄生式继承的问题:不能做到函数复用
			function object(o){
				function F(){};
				F.prototype=o;//将临时构造函数的原型设置为超类的对象.
				return new F();
			}
			
			function createAnother(original){
				var clone=object(original);
				clone.sayHi=function(){//添加函数后返回该对象,函数不共享
					console.log('hi');
				}
				return clone;				
			}
			
			var person={
				name:'张三',
				friends:['lily','nacy','tom']
			}
			
			var person2=createAnother(person);
			person2.sayHi();

六、寄生组合式继承(引用类型的理想继承)

基本思想: 寄生式继承+组合继承
  • 构造函数 继承 属性;原型链混成形式 继承 方法
			function object(o){
				function F(){};
				F.prototype=o;//将临时构造函数的原型设置为超类的对象.
				return new F();
			}
			
			//创建超类构造函数的副本,赋值给子类型的原型
			function  inheritPrototype(subType,superType){//两个参数:子类构造函数,父类构造函数
				var prototype=object(superType.prototype);//创建超类型原型的副本
				prototype.constructor=subType;
				subType.prototype=prototype;//将新创建的对象赋值给子类型的原型
			}
			
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值