class使用 —— ECMAScript 6入門讀書筆記

書籍地址: ECMAScript 6 入門

class在es6中就是一個語法糖,只是與es5定義類時候的寫法不一樣,功能還是一樣的

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    sayAge() {
        console.log(this.age);
    }
}

Person.prototype.sayName = function () {
    console.log(this.name);
};

裏面的nameage屬性在Person上,sayAgesayName方法在Person.prototype

this的使用

使用class定義的類的內部有this,他將默認指向類的實例

使用其他的方式定義一個類,並將裏面的方法取出來可以單獨使用

var myName = 'Windows name';
let obj = {
    myName: "obj name",
    say: function () {
        console.log(this.myName);
    }
};
obj.say();
//使用賦值解構的方式取出say
let { say } = obj;
say();

但是使用class定義的類,將裏面的方法取出來無法單獨使用

class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    sayName() {
        console.log(this);
        console.log(this.name);
    }
}
var name = "Windows name";
let person = new Person('hzj', 19);
let { sayName } = person;
sayName();

調用sayName方法的時候,發現thisundefined,所以無法使用this.name

解決方法

  • 最簡單的方法: 使用bind綁定this
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
        this.sayName = this.sayName.bind(this);
    }

    sayName() {
        console.log(this);
        console.log(this.name);
    }
}

set和get使用

定義的setget方法會改變某個屬性的存值行爲和取值行爲

class Person {
    constructor(name, age) {
        this._name = name;
        this.age = age;
    }

    get name() {
        console.log('調用了get name方法');
        return this._name;
    }

    set name(name) {
        console.log('調用了set name方法');
        this._name = name;
    }
}

let person = new Person("hzj", 22);
person.name = 'xm';
console.log(person.name);
console.log(person._name);

_name並不是私有的,可以直接取值和設置值,只是在命名上進行區別

靜態方法

使用static定義的方法不能在類的實例對象上使用,可以通過類.方法名()使用

static定義的方法可以被子類繼承,可以通過子類名.方法名()調用或者通過supper().方法名()調用

class Foo {
    constructor(name, age) {
    }

    static hello() {
        console.log('hello world');
    }
}

let foo = new Foo();

Foo.hello();

class Child extends Foo {
    static useHello() {
        super.hello();
    }
}

Child.hello();

Child.useHello();

即使是子類的實例對象,也不能夠使用父類的靜態方法

class Child extends Foo {
    useHello() {
        super.hello();
    }
}

let child = new Child();
child.useHello(); //TypeError: (intermediate value).hello is not a function

new.target

用來判斷是否使用new關鍵字創建的對象

  • 限制對象必須通過new使用
function Person(name, age) {
    if (new.target === undefined) {
        throw new Error('必須使用new關鍵字使用');
    } else {
        this.name = name;
        this.age = age;
    }
}

Person('hzj', 22);
let person = new Person('hzj', 22);
  • class中可以限定必須通過子類進行實例化,本身不能實例化
class Person {
    constructor(name, age) {
        if (new.target === Person) {
            throw new Error('必須使用new關鍵字生成實例');
        } else {
            this.name = name;
            this.age = age;
        }
    }
}

class Child extends Person {

    constructor(name, age, classes) {
        super(name, age);
        this.classes = classes;
    }
}

let child = new Child('hzj', 22, 1);
let person = new Person('hzj', 22); //Error: 必須使用new關鍵字生成實例

suppr必須在this的前面使用

這是錯誤的使用方式

constructor(name, age, classes) {
    this.classes = classes;
    super(name, age);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章