目录
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 foodconsole.log(monkey.eat()) //i am eat foodmonkey.eat = function () { console.log('error')}console.log(dog.eat()) //i am eat foodconsole.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 foodconsole.log(monkey.eat()) //i am eat foodmonkey.constructor.prototype.eat = function () { console.log('error')}console.log(dog.eat()) //errorconsole.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) // 4dog.age = 5console.log(dog.age) // 4 对age的赋值并没有失效
写属性
let _age = 4class 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) // 4dog.age = 5 // 符合条件,批改了age属性的值console.log(dog.age) // 5dog.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 fooddog.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
- 先继承Animal构造函数外部的属性和办法
- 再继承原型链上的属性和办法
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.prototypelet 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 fooddog.hello()// i am walking// dog eat food// and say hello