ES6-class類

1、基本語法
經過class關鍵字,能夠定義類。該方法定義的原型對象跟ES5定義的沒有多少區別,只是用class的寫法能讓對象原型的定義更加清晰,更像面向對象編程的語法。
一、基本語法:編程

class Person{
    constructor(name,age){
        this.name = name;
        this.age = age;
        this.fun = ()=>console.log('constructor內的方法能夠被遍歷到哦')
    }
    say() {
        console.log(`My name is ${this.name}`)
    }
}
let p1 = new Person('Liane',18)
p1.say()  //My name is Liane
//使用class建立的構造函數,全部的方法都會被定義在prototype屬性上面,所以是不可以被遍歷到的。
console.log(p1) //{name: 'Liane', age: 18,fun: f}
for(let k in p1){
    console.log(k) //name  //age  //fun
}
//因此,添加類的方法能夠使用Object.assign()方法,一次性向類添加多個方法
Object.assign(Person.prototype, {
    growUp(){
        return ++this.age
    },
    eat(food){
        console.log(`${this.name}吃了${food}`)
    }
})
p1.growUp()
console.log(p1.age)   //19
p1.eat('apple')
//也可以使用Object.getPrototypeOf(obj)方法獲取obj的原型對象,再爲原型添加方法或屬性
Object.getPrototypeOf(p1) === Person.prototype   //true

與ES5一致,實例對象p1的name、age、fun由於定義在this上,因此都是實例自身的屬性,用hasOwnProperty()檢查返回trueapp

console.log(p1.hasOwnProperty('name')) //true
console.log(p1.hasOwnProperty('fun'))  //true
console.log(p1.hasOwnProperty('say'))  //false
console.log(p1.__proto__.hasOwnProperty('say')) true

二、this的指向:
類的方法內部若是有this,它默認是指向類的實例,但若是將該方法提出來單獨使用,this會指向該方法運行時的環境。所以咱們能夠使用bind綁定this,或者使用箭頭函數來解決。函數

class Logger{
    printName(name){
        this.print(`Hello ${name}`)
    }
    print(text){
        console.log(text)
    }
}

const logger = new Logger();
const {printName} = logger;
printName('Liane')  //報錯

使用bind綁定thisthis

class Logger{
    constructor(){
        this.printName = this.printName.bind(this)
    }
    printName(name){
        this.print(`Hello ${name}`)
    }
    print(text) {
        console.log(text)
    }
}

const logger = new Logger();
const {printName} = logger;
printName('Liane')  //'Hello Liane'

使用箭頭函數prototype

class Logger{
    constructor(){
        this.printName =(name)=>this.print(`Hello ${name}`);
    }
    print(text) {
        console.log(text)
    }
}

const logger = new Logger();
const {printName} = logger;
printName('Liane')  //'Hello Liane'

三、採用class表達式建立類
a、使用類的名字Me,只在class內部使用,指當前類,在外部則必須使用變量名MyClass引用code

const MyClass = class Me{
    constructor(x,y){
        this.x = x;
        this.y = y;
    }
    getClassName(){
        return Me == this;
    }
}

let inst = new MyClass(1,2);
console.log(inst.getClassName())   //Me
console.log(inst.x)   //1

若內部不使用Me,可以下簡寫對象

const MyClass = class{
    /*...*/
}

採用class表達式可寫出當即執行的class繼承

let person = new class{
    constructor(name){
        this.name = name
    }
    sayName(){
        console.log(this.name)
    }
}('Liane');
person.sayName()  //Liane

四、靜態方法:
類至關於實例的原型,全部在類中定義的方法,都會被實例繼承,若是在一個方法前,加上static關鍵字,就表示該方法不會被實例繼承(能夠被子類繼承),而是經過類來調用,這就稱爲靜態方法原型鏈

class Foo{
    static fun(){
        console.log("I'm a static function")
    }
}

Foo.fun() //"I'm a static function"

var foo = new Foo()
foo.fun()  //TypeError:foo.fun is not a function

若static方法包含this,this指向類,而不是實例get

class Foo{
    static bar(){
        this.baz()
    }
    static baz(){
        console.log('Hello')
    }
    baz(){
        console.log('world')
    }
}
Foo.bar()   //'Hello'

靜態方法能夠被子類繼承

class Parent{
    static fun(){
        return 'Im a static fun'
    }
}

class Child extends Parent{
    foo(){
        return super.fun() + ', too'
    }
}

Child.fun()  //'Im a static fun'
Child.foo()  //'Im a static fun, too'

2、類的繼承
Class能夠經過extends關鍵字來實現繼承,這比ES5經過修改原型鏈實現繼承要清晰和方便得多。
語法:

class Person{
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    say(){
        console.log(`My name is ${this.name}`)
    }
}

class Student extends Person{
    constructor(x,y,score){
        super(x,y);  //super關鍵字,表示父類的構造函數,用來新建父類的this對象。
        this.score = score;
    }
}

let st1 = new Student('Liane',18,99)
console.log(st1){name: 'Liane', age: 18, score: 99}

子類必須在constructor方法中調用super方法,不然新建實例會報錯。由於子類本身的this對象必須先經過父類的構造函數完成塑造,獲得與父類一樣的實例屬性和方法。

判斷一個類是否繼承自另外一個類,能夠使用Object.getPrototypeOf()方法

Object.getPrototypeOf(Student)===Person //true
Object.getPrototypeOf(st1)===Person //fales
Object.getPrototypeOf(st1)===Student.prototype //true
相關文章
相關標籤/搜索