es6类的编译

1。一个单独的类

class Child{
	constructor(){
		this.age = 9;//私有属性
	}//注意每一个方法后面是没有逗号的,它是一个在一个类里面,不是在对象里面
	static a(){//静态方法,属于类上的方法
		return 1;
	}//有静态方法,没有静态属性static a = 1;会报错
	smoking(){//属于原型上的方法
		console.log('smoking');
	}
}
let child = new Child();
conso.log(Child.a());//类上的方法只能用类名来调用

2。类的继承

class Parent{
    constructor(){
        this.name = 'parent';
       // return {};
    }
    static b(){
        return 2;
    }
    eat(){
        console.log('eat');
    }
}
class Child extends Parent{
    constructor(){
        super();//Parent.call(this)
        this.age = 9;//私有属性
    }
    static a(){
		return 1;
	}
	smoking(){
		console.log('smoking');
	}
}
let child = new Child();
// console.log(child.eat());//eat
// console.log(child.name);//parent
// console.log(Child.b());//2
//类可以继承公有私有和静态方法
//父类的构造方法返回了引用类型,会把这个引用类型作为子类的this
console.log(child);//Child { name: 'parent', age: 9 }
                    //Child { age: 9 },如果constructor里面返回了一个{},那么返回的{}就会是this对象,那么就不会拿到父类的私有属性name

3。实现一个类的es6的编译过程

  1. 第一步就是类 的调用检测
  2. 第二步就是创建类,实现属性构造器来定义类的公有属性和静态方法
//  类的调用检测,instance是实例,constructor是构造函数
function _classCallcheck(instance, constructor){
    if(!(instance instanceof constructor)){
        throw new Error('Class constructor Parent Can not be invoked without new');
    }
}
//  constructor是构造函数,prototypePropertys是原型上方法的描述,staticPropertys是静态方法的描述
function _creatClass(constructor, prototypePropertys, staticPropertys){
    definePropertys(constructor.prototype, prototypePropertys);
    definePropertys(constructor, staticPropertys);
}
function definePropertys(target, arr){
    for(let i = 0; i < arr.length; i++){
        Object.defineProperty(target, arr[i].key, {
            ...arr[i],
            enumerable:true,
            configurable:true,
            writable:true,
        })
    }
}
let Parent = function(){
    function p(){
        _classCallcheck(this, p);//类的调用检测,只能用new Parent(),不能直接Parent()。
        this.age = 9;
    }
    //创建类
    _creatClass(p, //属性描述器
        [
            {
                key:'eat',
                value:function(){
                    console.log('吃');
                }
            }
        ],
        [
            {
                key:'b',
                value:function(){
                    return 2;
                }
            }
        ]
    )
    return p;
}();
let parent = new Parent();
parent.eat();
console.log(Parent.b());//静态的方法只能用类来调用

4。实现es6的类的继承的编译过程

//  类的调用检测,instance是实例,constructor是构造函数
function _classCallcheck(instance, constructor){
    if(!(instance instanceof constructor)){
        throw new Error('Class constructor Can not be invoked without new');
    }
}
//  constructor是构造函数,prototypePropertys是原型上方法的描述,staticPropertys是静态方法的描述
function _creatClass(constructor, prototypePropertys, staticPropertys){
    definePropertys(constructor.prototype, prototypePropertys);
    definePropertys(constructor, staticPropertys);
}
function definePropertys(target, arr){
    for(let i = 0; i < arr.length; i++){
        Object.defineProperty(target, arr[i].key, {
            ...arr[i],
            enumerable:true,
            configurable:true,
            writable:true,
        })
    }
}
let Parent = function(){
    function p(){
        _classCallcheck(this, p);//类的调用检测,只能用new Parent(),不能直接Parent()。
        this.name = 'parent';
        
    }
    //创建类
    _creatClass(p, //属性描述器
        [
            {
                key:'eat',
                value:function(){
                    console.log('吃');
                }
            }
        ],
        [
            {
                key:'b',
                value:function(){
                    return 2;
                }
            }
        ]
    )
    return p;
}();

function _inherits(subClass, superClass){
    //继承公有属性
    subClass.prototype = Object.create(subClass.prototype,{constructor:{value:subClass}});
    //继承类上的静态方法
    Object.setPrototypeOf(subClass,superClass)//subClass.prototype.__proto__= superClass.prototype
}
let Child = (function(Parent){//使用闭包和立即执行函数把父类传进来,其实就是实现了extends关键字,实现了继承
    _inherits(C,Parent);//先继承父类的公有属性和静态方法
    function C(){
        _classCallcheck(this,C);
        let obj = Parent.call(this);
        let that = this;
        if(typeof obj === 'object'){
            that = obj;//如果Parent.call(this)返回的是引用类型的对象,那么就把对象变成现在的this
        }
        that.age = 9;//如果返回的不会对象,那么就直接在this上添加私有属性。
        //解决了父类返回一个引用类型的问题
        return that;
    }
    return C;
})(Parent);
let child = new Child();
console.log(child);//C { name: 'parent', age: 9 }
console.log(Child.b());//2

猜你喜欢

转载自blog.csdn.net/weixin_43623871/article/details/89340879