乐趣区

关于javascript:ES6四-Class

目录

  • Class

    • 类的应用【申明、属性、办法、继承】
    • Basic Syntax —— 怎么申明一个类?

      • ES5
      • ES6
      • 类和结构函有什么区别?
    • Setters & Getters —— 如何读写属性?

      • ES5
      • ES6

        • getter / setter 是读写属性
    • Static Methods —— 如何操作一个办法?

      • ES5
      • ES6
      • 开发中什么时候用对象实例办法,什么时候用静态方法?
    • Sub Classes —— 怎么继承另一个类?

      • ES5
      • ES6
  • ES6-ES10 学习幅员

类的应用【申明、属性、办法、继承】

Basic Syntax —— 怎么申明一个类?

ES5

let Animal = function (type) {
    this.type = type
    this.eat = function () {console.log('i am eat food')
    }
}

let dog = new Animal('dog')
let monkey = new Animal('monkey')

console.log(dog.eat()) //i am eat food
console.log(monkey.eat()) //i am eat food

monkey.eat = function () {console.log('error')
}
console.log(dog.eat()) //i am eat food
console.log(monkey.eat()) //error
// eat 如果实例化之后进行批改,批改了 dog 的,那么 monkey 的不会扭转,这样就失去了继承的概念。如果是公共办法那么不要写在类的公有办法外面。

所以要把公共办法放在原型对象下面

let Animal = function (type) {this.type = type}
Animal.prototype.eat = function () {console.log('i am eat food')
}

let dog = new Animal('dog')
let monkey = new Animal('monkey')
console.log(dog.eat()) //i am eat food
console.log(monkey.eat()) //i am eat food
monkey.constructor.prototype.eat = function () {console.log('error')
}
console.log(dog.eat()) //error
console.log(monkey.eat()) //error

ES6

class Animal {constructor (type) {this.type = type}
    eat() {console.log('i am eat food')
    }
}

let dog = new Animal('dog')
let monkey = new Animal('monkey')

console.log(dog.eat())
console.log(monkey.eat())

类和结构函有什么区别?

没有区别,class 只是 ES5 用原型链申明构造函数的 语法糖
console.log(typeof Animal) //function

Setters & Getters —— 如何读写属性?

ES5

无奈实现读写属性的拦挡操作,只读属性等不好实现

ES6

getter / setter 是读写属性

读属性

class Animal {constructor (type) {this.type = type}
    //age 后面加一个 get / set,就变成了属性,es6 反对属性晋升到函数体最顶层,能够不全副写到 constructor 外面
    //get 是只读属性
    get age () {return 4}
    eat () {console.log('i am eat food')
    }
}

let dog = new Animal('dog')
console.log(dog.age) // 4
dog.age = 5
console.log(dog.age) // 4 对 age 的赋值并没有失效

写属性

let _age = 4
class Animal {constructor (type) {this.type = type}
    // 读取
    get age () {return _age // 返回值和属性名 age 不要一样}
    // 写入
    set age (val) {if (val < 7 && val > 4) {_age = val // 返回值和属性名 age 不要一样}
    }
    eat () {console.log('i am eat food')
    }
}

let dog = new Animal('dog')
console.log(dog.age) // 4
dog.age = 5 // 符合条件,批改了 age 属性的值
console.log(dog.age) // 5
dog.age = 8 // 不符合条件,没有批改 age 属性的值
console.log(dog.age) // 5

Static Methods —— 如何操作一个办法?

  • 对象实例办法
  • 类的静态方法

ES5

let Animal = function (type) {this.type = type}

// 对象实例办法
Animal.prototype.eat = function () {Animal.walk() // 这里不必 this,是因为这里的 this,指的是实例对象,而 walk 办法是在构造函数上,不在实例对象上
    console.log('i am eat food')
}

// 增加静态方法,通过类是能够拜访的,然而无奈通过实例对象拜访
Animal.walk = function () {console.log('i am walking')
}

let dog = new Animal('dog')
dog.eat()
//i am walking
//i am eat food
dog.walk() // dog.walk is not a function 报错

ES6

static 标识符能够实现

class Animal {constructor (type) {this.type = type}
    // 对象实例办法,类中间接定义方法就是实例对象的办法
    eat () {Animal.walk() 
        console.log(this) // 这里的类指的是 Animal, 不能在这里应用 this.type,因为 Animal 下面没有 type 属性,其原型对象上有 type 属性
        console.log('i am eat food')
    }
    // 增加静态方法,是通过 static 标识符进行辨别的
    static walk () {console.log('i am walking')
    }
}

let dog = new Animal('dog')
dog.eat()
//i am walking
//i am eat food

开发中什么时候用对象实例办法,什么时候用静态方法?

如果此函数外部有要应用实例对象的属性和办法的时候,那么必须定义为 类的实例对象办法
如果此函数外部不须要实例对象的内容,就应用 类的静态方法

Sub Classes —— 怎么继承另一个类?

面向对象之所以弱小,就是因为继承。

ES5

  1. 先继承 Animal 构造函数外部的属性和办法
  2. 再继承原型链上的属性和办法
let Animal = function (type) {this.type = type}

Animal.prototype.eat = function () {Animal.walk()
    console.log('i am eat food')
}

Animal.walk = function () {console.log('i am walking')
}
// 申明一个 Dog 构造函数,其继承 Animal 构造函数的,将 Animal 构造函数运行一下,并将其 this 指向 Dog 构造函数
let Dog = function () {
    // 1. 初始化父类的构造函数,应用 call 是扭转 this 的指向 Dog 的实例,前面是传入的参数,有多少依此往后排即可
    // 这里只能继承 Animal 构造函数外部的属性和办法
    Animal.call(this, 'dog')
}
// 2. 剩下一部分挂载在原型链上的继承,须要把 Dog 的原型链指向 Animal 的原型链 -- 援用类型
Dog.prototype = Animal.prototype
let dog = new Dog('dog')
dog.eat()
//i am walking
//i am eat food

ES6

extends 能够实现

class Animal {constructor (type) {this.type = type}
    eat () {Animal.walk()
        console.log(this.type + 'eat food')
    }
    static walk () {console.log('i am walking')
    }
}

// 用 extends 实现了继承,用其来示意 Dog 是 Animal 的子类
class Monkey extends Animal {
    // 默认执行了上面的语句,如果构造函数没有新增属性这样写,那么能够不必写
    // constructor (type) {// super(type) // 继承父类要执行父类的构造函数,专用办法
    // }
}
class Dog extends Animal {constructor (type) {
        // super 必须在构造函数第一行,否则报错,而且必须传参数
        super(type) 
        this.age = 2
    }
    hello () {
        // super 对象始终指向父类,调用它就是调用了父类的构造函数
        super.eat()
        console.log('and say hello')  
    }
}

let dog = new Dog('dog')
let monkey = new Monkey('monkey')
dog.eat()
monkey.eat()
// i am walking
// dog eat food
// i am walking
// monkey eat food
dog.hello()
// i am walking
// dog eat food
// and say hello

学习幅员

退出移动版