ES6部分源码重写 -1(ES5-构造函数解析)

ES6部分源码重写 -1

剖析ES5中对象的使用

创建一个飞机的对象
该对象具有以下属性和方法

  • 名称
  • 血量
  • 飞行方法
    此处将方法定义在飞机的原型上,从效率的角度来看更低
	Plane.prototype.fly = function(){
		console.log("fly");
	}
	function Plane(){
		this.name = name || "一般飞机";
		this.blood = 100;
	}
	//创建一个飞机的对象
	var plane =  new Plane("梦想号");

此时,因为军事实力的提升,我们的需求发生改变,需要生产具有攻击能力的战斗机
所以,我们在创建一个攻击机的构造工厂
因为后来生产的飞机是在已有工厂的前提下生产的,所以采用继承的方式来创造战斗机
此时飞机具有的功能有

  • 名称
  • 血量
  • 旋转
  • 飞行的方法
  • 攻击的方法
    此处的继承分为
  • 继承私有属性(指的是继承Plan里的私有变量,eg: name/blood)
  • 继承原型上的方法(eg:fly)
    继承私有属性
	function AttackPlane(){
		Plane.apply(this, "歼击机-01");
		this.rotate = true;
	}

继承原型上的方法有很多种,如下(此处使用父类和子类代替飞机的关系)

  1. 直接将父类的原型赋值给子类的原型
    • 这种方式的缺点:如果在子类的原型上添加一个方法,那么父类的原型上也会添加相应的方法
	AttackPlane.prototype = Plane.prototype;
	AttackPlane.prototype.attack = function(){
		console.log("轰炸中。。。。");
	}
	function AttackPlane(){
		Plane.apply(this, "歼击机-01");
		this.rotate = true;
	}
	var plane1 = new Plane();

控制台看效果
在这里插入图片描述
所以采用此种方法继承会导致父类多出不需要的方法

2.将父类的对象new一个实例赋予子类的原型

   	AttackPlane.prototype = new Plane();
   	AttackPlane.prototype.attack = function(){
   		console.log("轰炸中。。。。");
   	}
   	function AttackPlane(){
   		Plane.apply(this, "歼击机-01");
   		this.rotate = true;
   	}
   	var plane1 = new Plane();


采用new Plane的方式会导致子类的原型上会将父类的私有属性继承下来,所以也不合适

  1. 使用中间变量的方式
   let temp = function () { };
   temp.prototype = Plane.prototype;
   AttackPlane.prototype = temp.prototype;
   AttackPlane.prototype.attack = function () {
       console.log("轰炸....");
   }
   AttackPlane.prototype.attack = function () {
       console.log("轰炸中。。。。");
   }
   function AttackPlane() {
       Plane.apply(this, "歼击机-01");
       this.rotate = true;
   }
   var plane1 = new Plane();

在这里插入图片描述
此种方式也没有避免子类的方法顺着原型链传到父类的身上

4.采用

  • Object.create();方法;
  • Object.setPrototypeOf();方法;
  • 构造函数的原型的__proto__ = 父类的原型
    上面的三种方式都能实现圣杯模式的继承
    选中其中一个来写使用即可
	//这种方法写起来比较复杂,没有兼容性问题
   AttackPlan.prototype = Object.create(Plan.prototype, {
       constructor:AttackPlan
   })
   //老版本浏览器会有兼容性问题,有时需要左兼容性处理,采用最多
   AttackPlan.prototype = Object.setPrototypeOf(AttackPlan.prototype, Plan.prototype);
   //最粗暴的方法,大佬的做法
   AttackPlan.prototype.__proto__ = Plan.prototype;
   AttackPlane.prototype.attack = function () {
       console.log("轰炸....");
   }
   AttackPlane.prototype.attack = function () {
       console.log("轰炸中。。。。");
   }
   function AttackPlane() {
       Plane.apply(this, "歼击机-01");
       this.rotate = true;
   }
   var plane1 = new Plane();

这三种情况下,都能避免子类的的方法污染父类的方法
也不会使父类的私有变量跑到子类的原型上去

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值