Es6 Class是如何實現的?

在Es5中沒有類的概念,在將類以前咱們首先要說一下類的繼承javascript

類的繼承

類有三種屬性,,公有屬性,私有屬性, 靜態屬性(Es7)/靜態類(Es6)java

如何實現一個類

  • 繼承公有屬性
function Parent(){
    this.name = 'parent';
}
new Parent();//this指向當前實例
Parent() //this指向window
function Child(){
    this.age = 9;
    Parent.call(this);//至關於this.name = 'parent' //繼承私有屬性
}
複製代碼
  • 繼承父類屬性
    • 嚴格來講,通常規範帶下劃線的就叫私有,即便繼承,類的私有屬性也不會繼承,私有屬性只有類的內部方法能訪問的屬性,咱們這裏將原有繼承私有屬性改成繼承父類屬性,對給你們帶來的誤解和困擾表示抱歉,文章有誤的地方歡迎你們評論,謝謝你們!謝謝 @MrTreasure!
function Parent(){
    this.name = 'parent';
}
Parent.prototype.eat = function(){
    console.log('eat')
}
function Child(){
    this.age = 9;
    Parent.call(this);//至關於this.name = 'parent' //繼承私有屬性
}
Child.prototype.smoking = function(){
    console.log('smoking')
}
Child.prototype = Parent.prototype;//這個不叫繼承
//由於這樣若是改變 Child.prototype 加屬性,Parent.prototype的實例也會有這個屬性,,此時這二者屬於兄弟關係

Child.prototype._proto_ = Parent.prototype   // 方法一
//object.create
Child.prototype = object.create(Parent.prototype); // 經常使用,方法二
function create(parentPrototype,props){
    function Fn(){}
    Fn.prototype = parentPrototype;
    let fn = new Fn();
    for(let key in props){
        Object.defineProperty(fn,key,{
            ...props[key],
            enumerable:true
        });
    }
    return fn();
}
Child.prototype = create(Parent.prototype,{constructor:{value:Child}})

![](https://user-gold-cdn.xitu.io/2018/5/28/163a486d1740a83f?w=1220&h=634&f=png&s=369712)

複製代碼
  • 繼承公有屬性和私有屬性 Child.prototype = new Parent()

類的編譯

  1. 類只能new
class Parent{
    //私有屬性
    constructor(){
        this.name = 'parent',
        this.age = '40'
    }
    //公有屬性,原型上的方法
    eat(){
        console.log('eat')
    }
    //靜態方法/屬性 es6/es7
    //屬於類上的方法 Child.a()
    static b(){
        return 2
    }
}
new Parent();
class Child extends Parent{ //繼承父親的私有和公有
    //私有屬性
    constructor(){
        super() // 至關於Parent.call(this)
        this.name = 'child'
    }
    //公有屬性,原型上的方法
    smoking(){
        console.log('smoking')
    }
    //靜態方法/屬性 es6/es7
    //屬於類上的方法 Child.a()
    static a(){
        return 1
    }
}
let child = new Child();
console.log(child.name,child.age,child.eat(),child.smoking,Child.b())
//類能夠繼承公有,私有和靜態
//父類的構造函數中返回類一個引用類型,會把這個引用類型做爲子類的this
複製代碼

咱們首先寫一個建立類的函數node

//檢測實例是否是new出來的
function _classCallCheck(instance,constructor){
  if(!(instance instanceof constructor)){
    throw new Error('Class constructor Child cannot be invoked without new')
  }
}
//constructor構造函數
//prprotoPropertys構造函數原型
//staticPropertys靜態方法的描述
function definePropertys(target,arr){
  for(let i=0;i<arr.length;i++){
    Object.defineProperty(target,arr[i].key,{
      ...arr[i],
      configurable : true,
      enumerable : true,
      writable:true
    })
  }
}
function _createClass(constructor,protoPropertys,staticPropertys){
  if(protoPropertys.length > 0){
    definePropertys(constructor.prototype,protoPropertys)
  }
  if(staticPropertys.length > 0){
    definePropertys(constructor,staticPropertys)
  }
}
let Parent = function(){
  //寫邏輯
  function P(){
    _classCallCheck(this,P)
    this.name = 'parent';
    //return {}
  }
  _createClass(P,//屬性描述器
    [
      {
        key: 'eat',
        value: function () {
          console.log('吃')
        }
      }
    ],
    [
      {
        key:'b',
        value:function () {
          return 2;
        }
      }
    ]
  )
  return P;
}()
let p = new Parent();
console.log(p.eat())
複製代碼

上面這個函數沒有繼承做用,下面咱們逐步完善es6

類的繼承

function _inherits(subClass,superClass){
  //繼承公有屬性
  subClass.prototype = Object.create(superClass.prototype,{constructor:{
    value:subClass
  }})
  //繼承靜態方法
  Object.setPrototypeOf(subClass,superClass);
}
let Child = (function(Parent){
  _inherits(C,Parent)
  //繼承私有屬性
  function C(){
    _classCallCheck(this,C);
    let that = this;
    let obj = Parent.call(this);//繼承並執行父類
    if(typeof obj === 'object'){
      that = obj
    }
    that.age = 9 ; //解決了父類返回引用類型的問題
  } 
  return C;
})(Parent)
let child = new Child()
console.log(child)
console.log(Child.b())
console.log(parent)

[Running] node "/Users/myloveyunyun/Desktop/node/pro.js"
C { name: 'parent', age: 9 }
2
P { name: 'parent' }

複製代碼

這樣咱們的類就建立完成了函數

相關文章
相關標籤/搜索