js es6 类,抽象

function print(txt) {
    console.log(txt)
}
//类定义几种方式
//方式1
let MyClass = class My {
    constructor() {

    }

    getClassName() {
        return My.name;
    }
};

let inst = new MyClass();
print(MyClass.name)//My
print(inst.getClassName());//My
// new My(); ReferenceError: My is not defined
// My.name   ReferenceError: My is not defined
//方式2
let MyClass2 = class {
    constructor() {

    }

    getClassName() {
        return 'MyClass2'
    }
};
print(MyClass2.name)//MyClass2
print(new MyClass2().getClassName())//MyClass2

//方式3
class MyClass3 {
    constructor() {

    }

    getClassName() {
        return 'MyClass3'
    }
}
print(MyClass3.name)//MyClass3
print(new MyClass3().getClassName())//MyClass3

//方式4
let inst4 = new class {
    constructor(value) {
        this.value = value;
    }

    getValue() {
        return this.value;
    }
}('通过构造函数初始化');
print(inst4.name)//undefined
print(inst4.getValue())//通过构造函数初始化


/////////this的指向//////////////
class Logger {
    printName(name = 'there') {
        this.print(`hello ${name}`);
    }

    print(txt) {
        console.log(txt);
    }
}

let logger = new Logger();
let {printName} = logger;
// printName()   TypeError: Cannot read property 'print' of undefined
// printName方法中的this,默认指向Logger类的实例。但是,如果将这个方法提取出来单
// 独使用,this会指向该方法运行时所在的环境,因为找不到print方法而导致报错。


// 可以在构造方法中绑定this,这样就不会找不到print方法了。
class Logger2 {
    constructor() {
        this.printName2 = this.printName2.bind(this);
    }

    printName2(name = 'there') {
        this.print(`hello ${name}`);
    }

    print(txt) {
        console.log(txt);
    }
}
let logger2 = new Logger2();
let {printName2} = logger2;
printName2(); //hello there


/////////////类继承 及 get set///////////////
class Parent {
    constructor(v1, v2) {
    }

    static who() {
        return 'parent'
    }
}
class Child extends Parent {
    constructor() {
        super('value1', 'v2');
    }

    get name() {
        console.log('get name...');
        return this._name;
    }

    set name(name) {
        console.log('set name...' + name)
        // this.name=name;  不可以在 set 内部再次使用this.name
        this._name = name;
    }

    static who() {
        return 'child'
    }

}
print(new Child() instanceof Parent)//true
print(new Child() instanceof Object)//true

let child = new Child();
child.name = 'xiaoming'//赋值时调用set name(name){}
print(child.name)//xiaoming 取值时调用 get name(){}


print(Parent.who())//parent
print(Child.who())//child

print('--------iterator--  for of  -------')
class List {
    constructor(...args) {
        this.args = args;
    }

    *[Symbol.iterator]() {
        for (let arg of this.args) {
            yield arg;
        }
    }

    // *[Symbol.iterator]() {
    //     for (let arg in this.args) {
    //         yield arg;
    //     }
    // }
}
let list = new List('abc', 'def', 'ghi');
for (let item of list) {
    print(item)
}
// abc
// def
// ghi

// for (let item in list) {  //for in 无法遍历
//     print(item)
// }


// 实现类似java的抽象类
// 如果构造函数不是通过new命令调用的,new.target会返回undefined,
// 因此这个属性可以用来确定构造函数是怎么调用的。
// 子类继承父类时,new.target会返回子类。
class Shape {
    constructor() {
        if (new.target === Shape) {
            throw new Error('本类不能实例化');
        }
    }
}

class Rectangle extends Shape {
    constructor(length, width) {
        super();
        print('new ? ' + (new.target === Rectangle))
    }
}

// new Shape();  报错
new Rectangle(3, 4);  // 正确  new ? true

你可能感兴趣的:(js)