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);
}

你可能感兴趣的:(读书笔记,JavaScript,读书笔记,js,es6)