ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
之前用函数模拟类
function Person(name, age) { this.name = name; this.age = age } Person.prototype = { showName() { return 'my name is ' + this.name }, showAge() { return 'my age is ' + this.age } } let person = new Person('dou', 18) console.log(person.showName()) console.log(person.showAge())也可以将新增的方法放在一个对象里合并到原型上
function Person(name,age){ this.name = name; this.age = age; } Object.assign(Person.prototype,{ showName(){ return `我的名字是:${this.name}`; }, showAge(){ return `我的名字是:${this.age}`; } }) let p1 = new Person("wuwei",18); console.log(p1.showName()); console.log(p1.showAge());这个写法无非代码更优雅一点,无非都是在原型上加东西
constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
class Fn { } // 等同于 class Fn { constructor() {} }constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象。
class Foo { constructor() { return Object.create(null); } } new Foo() instanceof Foo // false //constructor函数返回一个全新的对象,结果导致实例对象不是Foo类的实例。类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。
class Foo { constructor() { return Object.create(null); } } Foo() // TypeError: Class constructor Foo cannot be invoked without 'new'如果要是用变量,那么就要使用[]的表达式
var aaa = 'wu'; class Person{ constructor(name,age){ this.name = name; this.age = age; } [aaa](){ return `此时属性名是一个变量,就是wu` } } // console.log(typeof Person) let p1 = new Person("wuwei",18); console.log(p1.wu()); // 此时不能通过aaa调用函数,aaa是变量,通过wu调用,可以通过[aaa]调用 p1[aaa]();这里就可以发现属性名可以为表达式
var aa = 'wu'; var bb = 'wei'; var obj = { [aa + bb]: "无为" }也就是说如果写法会报错
var p1 = new Person() console.log(p1); class Person{ constructor(){ this.name = "aaa" } }但是以前通过ES5 构造函数模拟类是可以变量提升的,因为本身就是函数
// 这种写法构造函数会提升,正常打印一个对象 var p1 = new Person() console.log(p1); this.name = "aaa" }class 里面有两个函数负责取值和存值,用的比较少
取值函数 get 存值函数 set
class Person{ constructor(name,age){ this.name = name; this.age = age; } get aa(){ console.log(`成功获取a的值`) return this.age; } set aa(val){ console.log(`成功设置a的值为${val}`); this.age = val; } } var p1 = new Person('wuwei',18)类相当于实例的原型,所有在类中定义的方法,都会被实例继承。
如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
ES6 明确规定,Class 内部只有静态方法,没有静态属性。
class Person{ constructor(name,age){ this.name = name; this.age = age; } showName(){ return `这是通过构造对象调用方法`; } static aaa(){ return `这是静态方法,是通过类来调用的方法`; } } var p1 = new Person('wuwei',18) console.log(p1.showName); console.log(Person.aaa());子类继承父类
通过super()扩展自己的属性和方法
// 父类 class Student { constructor(name, age, number) { this.name = name; this.age = age; this.number = number; } play() { return 'playing games' } } // 子类继承父类 class Dou extends Student { constructor(name, age, number) { // 继承父类得的属性 super(name, age, number) } // 父类的方法会默认继承 // 子类自己的方法 read() { return 'reading...' } } let dou = new Dou('dou', 18, '111') console.log(dou.play()); console.log(dou.read())