class类的使用

我们在ES5中经常使用方法或者对象去模拟类的使用,虽然可以实现功能,但是代码并不优雅,ES6为我们提供了类的使用。

需要注意的是我们在写类的时候和ES5中的对象和构造函数要区分开来,不要学混了。

类的声明

先声明一个最简单的coder类,类里只有一个name方法,方法中打印出传递的参数。
class coder{
    name(val){
        console.log(val);
    }
}

类的使用

我们已经声明了一个类,并在类里声明了name方法,现在要实例化类,并使用类中的方法。
class Person {
  name = "hello word";
  getName() {
    return this.name;
  }
}
const person = new Person();
console.log(person.getName()); // hello word

变量提升

const let class 不支持变量提升

例如 下面 运行 第一个console 输出a是会报错的

var a = 1;
function test() {
  console.log(a);
  class a {}
  console.log(a);
}
test();  // 相当于 window.test()

类的多方法声明

class Coder{
    name(val){
        console.log(val);
        return val;
    }
    skill(val){
        console.log(this.name('js')+':'+'Skill:'+val);
    }
}

let zachary= new Coder();
zachary.name('js');
zachary.skill('web');
需要注意的是两个方法中间不要写逗号了,这里的this指类本身,注意return 的用法。

类的传参

在类的参数传递中我们用constructor( )进行传参。传递参数后可以直接使用this.xxx进行调用。
class Coder{
    name(val){
        console.log(val);
        return val;
    }
    skill(val){
        console.log(this.name('js')+':'+'Skill:'+val);
    }

    constructor(a,b){
        this.a=a;
        this.b=b;
    }

    add(){
        return this.a+this.b;
    }
}

let zachary=new Coder(1,2);
console.log(zachary.add());
我们用constructor来约定了传递参数,然后用作了一个add方法,把参数相加。这和以前我们的传递方法有些不一样,所以需要多注意下。

class的继承

如果你学过java,一定知道类的一大特点就是继承。ES6中也就继承,在这里我们简单的看看继承的用法。
class Person {
  name = "hello word";
  getName() {
    return this.name;
  }
}
class Teacher extends Person {
  getTname() {
    return "xx老师";
  }
}
const teacher = new Teacher();
console.log(teacher.getName(), teacher.getTname()); // hello word xx老师

重写(子类可以重写父类的东西)

class Person {
  name = "hello word";
  getName() {
    return this.name;
  }
}
class Teacher extends Person {
  getTname() {
    return "xx老师";
  }
  getName() { //  重写父类的getName方法
    return "909";
  }
}
const teacher = new Teacher();
console.log(teacher.getName(), teacher.getTname()); // 909 xx老师

super 执行extends继承过来的父类方法

如果子类调用constructor,那么子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,

而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
在构造函数中使用时,super关键字单独出现,必须在可以使用this关键字之前使用。此关键字也可用于调用父对象上的函数。
super拥有父类的全部方法
使用场景就是当子类重写了父类的方法  但覆盖后还想调用父类的方法就可以使用super

class Person {
  name = "hello word";
  getName() {
    return this.name;
  }
}
class Teacher extends Person {
  getTname() {
    return "xx老师";
  }
  getName() {
    return super.getName() + " 909";
  }
}
const teacher = new Teacher();
console.log(teacher.getName(), teacher.getTname()); // hello word 909 xx老师

 get和set的使用

// 错误写法
class Phone {
  constructor(p) {
    this.p = p;
  }
  get p() {
    return 999;
  }
}
let newPhone = new Phone(888);
console.log(newPhone.p);

// 正确写法
class Phone {
  constructor(p) {
    this.p = p;
  }
  get p() {
    return 999;
  }
  set p(newVal) {
    console.log("新值", newVal);
  }
}
let newPhone = new Phone(888);
console.log(newPhone.p);

说明:class的set和get是成对存在的 和Object.defineProperty一样成对存在 少一个就会报错

 

使用实例

class BaseModel {
    constructor(data,message){
        if(typeof data === 'string'){
            this.message = data
            data = null
            message = null
        }
        if(data){
            this.data = data
        }
        if(message){
            this.message = message
        }
    }
}
class SuccessModel extends BaseModel{
    constructor(data,message){
        super(data,message)
        this.error = 0
    }
}
class ErrorModel extends BaseModel{
    constructor(data,message){
        super(data,message)
        this.error = -1
    }
}

module.exports = {
    SuccessModel,
    ErrorModel
}
大致就是 两处不同的error错误状态不一样 一个-1一个0
但是结构是一样的所以 可以共用父级结构 
先继承父级结构  之后通过子类DIY
class coders {
  constructor(a, b) {
    this.a = a;
    this.b = b;
  }
  name() {
    return this.a + this.b;
  }
}
class childer extends coders {
  constructor(a, b) {
    super(a, b);
    this.c = 3;
  }
}
let code = new childer(1, 2);
console.log(code); // childer { a: 1, b: 2, c: 3 }

 类的扩展延伸

  // jQuery就是一个class类
  // 里面的经典获取元素$() 就是jquery的一个实例化
  // 就是下面这样封装的
  window.onload = function () {
    window.$ = function (dom) {
      return document.querySelector(dom)
    }
    $('#box').style.cssText = "width:20px;height:20px;border:solid 1px red;"
  }
  /* 写在class中 */
  class jQuery {
    constructor(select) {
      let slice = Array.prototype.slice
      // 操作变成数组 因为可能是多个节点 下面两种方式都可
      // let dom = slice.call(document.querySelectorAll(select))
      let dom = Array.from(document.querySelectorAll(select))
      let len = dom ? dom.length : 0
      for (let i = 0; i < len; i++) {
        this[i] = dom[i]
      }
      this.length = len
      this.select = select || ''
    }
    append(node) {

    }
    addClass(name) {

    }
    html(data) {

    }
    /* 省略若干API */
  }
  window.onload = function () {
    window.$ = function (select) {
      // 工厂模式
      return new jQuery(select)
    }
    console.log($('li')[0])
  }

嵌套使用 

class Car {
    constructor(number, name) {
        this.number = number
        this.name = name
    }
}
class Kuaiche extends Car {
    constructor(number, name) {
        super(number, name)
        this.price = 1
    }
}
class Zhuanche extends Car {
    constructor(number, name) {
        super(number, name)
        this.price = 2
    }
}

class Trip {
    constructor(car) {
        this.car = car
    }
    start() {
        console.log(`行程开始,名称: ${this.car.name}, 车牌号: ${this.car.price}`)
    }
    end() {
        console.log('行程结束,价格: ' + (this.car.price * 5))
    }
}

let car = new Kuaiche(5, '宝来')
let trip = new Trip(car)
trip.start()
trip.end()

 

posted @ 2017-07-24 19:02  Model-Zachary  阅读(344)  评论(0编辑  收藏  举报