ES6部分源码重写 -3(ES6-ES5的方式来手写部分源码)

时间:2022-07-25
本文章向大家介绍ES6部分源码重写 -3(ES6-ES5的方式来手写部分源码),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

ES6中的多出的功能

主要完成一下几个功能

  • 对象必须要new的方式才能出来
  1. 创建对象
    • 这里创建对象的方法采用立即执行函数,封闭作用域,避免将私有变量暴露
    • 因为使用了立即执行函数,执行后就销毁,所以需要将构造函数返回给Plane这个变量
	var Plane = (function(){
		function Plane(name){
			this.name = name || "一般飞机";
			this.blood = 100;
		}
		return Plane;
	})()
  • 定义原型上的方法和静态方法
    1. 实现ES6中的构造函数必须通过new的方式来创建
    • 这里判断是不是new的主要方式是通过是不是new出来的
    • 如果是new出来的this指向的是Plane,如果不是new出来的,this指向的是window
	function _classCallCheck(_this,_constructor){
		if(!(_this instanceof _constructor)){
			throw new TypeError(" Class constructor Plane cannot be invoked without 'new'");
		}
	}
	var Plane = (function(){
		function Plane(name){
				_classCallCheck(this, Plane);
				this.name = name || "一般飞机";
				this.blood = 100;
			}
			return Plane;
	})()

不通过new的方式创建

通过new的方式创建

  • 添加原型上的方法和静态方法
    • 先创建一个子类的对象,用做继承使用
    • 将Plane构造函数传入立即执行函数中,避免每次都去全局中取,节省开发效率
    • 继承父类的私有属性Plane.apply(this, Plane);
    • 继承原型上的方法
	//封装原型上的方法和构造函数上的方法
	function _createClass(_constructor, _prototypeProperties, _staticProperties){
		if(_prototypeProperties){
			defineProperties(_constructor.prototype, _prototypeProperties);
		}
		if(_staticProperties){
			defineProperties(_constructor, _staticProperties);
		}
	}
	function defineProperties(target, prop){
		//将_prototypeProperties, _staticProperties中的对象拿出来循环
		prop.forEach(function(ele){
			//diao'yong
			Object.defineProperty(target,ele.key,{
				value: ele.value,
				writable: true,
            	configurable: true
			})
		})
	}
	//检测是否是通过new的方式创建对象
	function _classCallCheck(_this,_constructor){
		if(!(_this instanceof _constructor)){
			throw new TypeError(" Class constructor Plane cannot be invoked without 'new'");
		}
	}
	var Plane = (function(){
		function Plane(name){
				_classCallCheck(this, Plane);
				this.name = name || "一般飞机";
				this.blood = 100;
			}
			_createClass(AttackPlane, [
			{
				key: "fly",
				value: function (){
						console.log("fly");
				}
			}
		], [
				{
					key: "alive",
					value: function(){
						return true;
					}
				}
			]);
			return Plane;
	})()

	var AttackPlane = (function(Plane){
		function AttackPlane(){
			Plane.apply(this, Plane);
			this.logo = "duyi";
		}
		_createClass(AttackPlane, [
			{
				key: "fly",
				value: function (){
						console.log("fly");
				}
			}
		], [
				{
					key: "alive",
					value: function(){
						return true;
					}
				}
			]);
		return AttackPlane;
	})(Plane)
  • 子类继承父类
    • 此处子类继承父类调用的是ES6的方式,如果老版本的浏览器不支持,需要做兼容性处理, 使用的是AttackPlane.prototype.proto = Plane.prototype;此处就没有去做兼容性处理了
	//继承的方法
	function _inherit(sub, sup){
		Object.setPrototypeOf(sub.prototype, sup.prototype);
	}
	//封装原型上的方法和构造函数上的方法
	function _createClass(_constructor, _prototypeProperties, _staticProperties){
		if(_prototypeProperties){
			defineProperties(_constructor.prototype, _prototypeProperties);
		}
		if(_staticProperties){
			defineProperties(_constructor, _staticProperties);
		}
	}
	function defineProperties(target, prop){
		//将_prototypeProperties, _staticProperties中的对象拿出来循环
		prop.forEach(function(ele){
			//diao'yong
			Object.defineProperty(target,ele.key,{
				value: ele.value,
				writable: true,
            	configurable: true
			})
		})
	}
	//检测是否是通过new的方式创建对象
	function _classCallCheck(_this,_constructor){
		if(!(_this instanceof _constructor)){
			throw new TypeError(" Class constructor Plane cannot be invoked without 'new'");
		}
	}
	var Plane = (function(){
		function Plane(name){
				_classCallCheck(this, Plane);
				this.name = name || "一般飞机";
				this.blood = 100;
			}
			_createClass(AttackPlane, [
			{
				key: "fly",
				value: function (){
						console.log("fly");
				}
			}
		], [
				{
					key: "alive",
					value: function(){
						return true;
					}
				}
			]);
			return Plane;
	})()

	var AttackPlane = (function(Plane){
		_inherit(AttackPlane, Plane);
		function AttackPlane(){
			Plane.apply(this, Plane);
			this.logo = "duyi";
		}
		_createClass(AttackPlane, [
			{
				key: "fly",
				value: function (){
						console.log("fly");
				}
			}
		], [
				{
					key: "alive",
					value: function(){
						return true;
					}
				}
			]);
		return AttackPlane;
	})(Plane)
	var plane = new Plane("梦想号");
	var apPlane = new AttackPlane("歼击机-01");
  • 到此还有一个小问题需要注意
    • 如果父类构造函数返回的是一个对象,子类继承的时候继承的将会失败,所以再做一下处理

先看一下刚才所述的情况

此处子类继承的对象就不是父类属性 所以此处需要再做一下处理

	//继承的方法
	function _inherit(sub, sup){
		Object.setPrototypeOf(sub.prototype, sup.prototype);
	}
	//封装原型上的方法和构造函数上的方法
	function _createClass(_constructor, _prototypeProperties, _staticProperties){
		if(_prototypeProperties){
			defineProperties(_constructor.prototype, _prototypeProperties);
		}
		if(_staticProperties){
			defineProperties(_constructor, _staticProperties);
		}
	}
	function defineProperties(target, prop){
		//将_prototypeProperties, _staticProperties中的对象拿出来循环
		prop.forEach(function(ele){
			//diao'yong
			Object.defineProperty(target,ele.key,{
				value: ele.value,
				writable: true,
            	configurable: true
			})
		})
	}
	//检测是否是通过new的方式创建对象
	function _classCallCheck(_this,_constructor){
		if(!(_this instanceof _constructor)){
			throw new TypeError(" Class constructor Plane cannot be invoked without 'new'");
		}
	}
	var Plane = (function(){
		function Plane(name){
				_classCallCheck(this, Plane);
				this.name = name || "一般飞机";
				this.blood = 100;
				return {
					son: "xixi"
				}
			}
			_createClass(AttackPlane, [
			{
				key: "fly",
				value: function (){
						console.log("fly");
				}
			}
		], [
				{
					key: "alive",
					value: function(){
						return true;
					}
				}
			]);
			return Plane;
	})()

	var AttackPlane = (function(Plane){
		_inherit(AttackPlane, Plane);
		function AttackPlane(){
			var _this = this;
			var that = Plane.apply(_this, Plane);
			if(typeof that == "object"){
				_this = that;
			}
			_this.logo = "duyi";
			return _this;
		}
		_createClass(AttackPlane, [
			{
				key: "fly",
				value: function (){
						console.log("fly");
				}
			}
		], [
				{
					key: "alive",
					value: function(){
						return true;
					}
				}
			]);
		return AttackPlane;
	})(Plane)
	var plane = new Plane("梦想号");
	var apPlane = new AttackPlane("歼击机-01");

修改了子类的的构造函数的方法以后,可以成功的解决刚才的问题 效果如下图