用es5重寫es6 class來理解語法糖類

引言

最初接觸es6class是react全面向es6兼容的時候,那時候class類屬性跟方法的寫法已經this指針的指向弄得焦頭爛額,後來學會了用箭頭函數去綁定this,開始漸漸解決了this的問題。隨着react熟練度的增長,對類的'熟練度'看似增長了,實際還停留在不懂的階段,此次趁重學前端的機會,紮紮實實的去看待一下這個有用的語法糖。html

理理常見class的常見用法

class Person {
    constructor(name) {    // 1
        console.log(this)
        this.name = name
    }
    
    static state={}        // 2
    
    state1={}              // 3
    
    sayname() {            // 4
        console.log(this)
    }
    
    sayname2 = () => {          // 5
        console.log(this)
    }
    
    static sayname3() {         // 6
        console.log(this)
    }
    
    get html() {                // 7
        console.log(this)
        return 'html'
    }
    
    set html(name) {            // 8
        console.log(this)
        this.name = name
    }
}

const person = new Person('Jim')
複製代碼

es6的class是能夠看做只是一個語法糖,它的大部分功能都能用es5語法重寫。咱們平時用到的類的寫法大概有以上幾種,那上面的類轉化成es5的語法要怎麼寫?咱們從兩個方面來理解:前端

  1. 從類屬性或者方法歸屬來看:
  • 1 很好理解表明類的構造函數
  • 2 靜態方法state,經過Person.state 訪問
  • 3 state1,是this.state1={} 的簡寫,es7的語法,是實例person的私有屬性,經過person.state1訪問
  • 4 sayname至關於Person.prototype.sayname,掛在Person的原型鏈上,可經過Person.prototype.sayname或者person.sayname訪問
  • 5 sayname2同3,至關於this.sayname2=()=>{},屬於實例的私有屬性
  • 6 sayname3同2,Person的靜態屬性經過Person.sayname3 訪問
  • 7.8 訪問器屬性get/set ,掛在Person.prototype上,可經過Person.prototype.sayname或者person.sayname訪問
  1. 從訪問內部this指針來看
  • 1 constructor裏的this在實例初始化的時候生成,指向實例
  • 4 sayname至關於Person.prototype.sayname(),指向Person.prototype,person.sayname()實例調用時指向person
  • 5 sayname2至關於this.sayname2,因此只能在實例中調用,this指向person
  • 6 sayname3是靜態屬性,Person.sayname3(),天然指向的是父類Person
  • 7/8 同4,定義在prototype上
  1. 最後咱們用es5的語法來實現如下以上的Person
let Person = (function(){
    'use strict'
    // constructor
    const Person = function(name) {
        // 元屬性new.target確保是經過new調用的
        if(typeof new.target === 'undefined') {    
            throw new Error('必須經過new關鍵字調用')
        }

        this.name = name
        this.state1 = {}
        this.sayname2 = (function() {}).bind(this)
    }
    
    // static state
    Person.state = {} 
    // static sayname3
    Person.sayname3 = function() {}
    // sayname
    Object.defineProperties(Person.prototype, 'sayname', {
        value: function() {
            // 元屬性new.target確保是經過new調用的
            if(typeof new.target === 'undefined') {    
                throw new Error('必須經過new關鍵字調用')
            }
            console.log(this)
        },
        enumerable: false,
        writable: true,
        configurable: true
    })
    // html set
    Object.defineProperties(Person.prototype, 'html', {
        get: function() {
            console.log(this)
            return 'html'
        },
        set: function(name) {
            console.log(this)
            this.name = name
        },
        enumerable: false,
        configurable: true
    })
})()複製代碼
相關文章
相關標籤/搜索