类的介绍
JavaScript 语言中,生成实例对象的传统方法是通过构造函数,上面这种写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大,很容易让新学习这门语言的程序员感到困惑
//es5造类
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayName = function () {
return this.name;
}
Person.prototype.sayAge = function () {
return this.age;
}
let p1 = new Person('Max', 23);
console.log(p1); //Person {name: "Max", age: 23}
console.log(p1.sayName()); //Max
console.log(p1.sayAge()); //23
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类
基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的class改写,就是下面这样
//es6造类
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName() {
return this.name;
}
sayAge() {
return this.age;
}
}
let p1 = new Person('Max', 23);
console.log(p1); //Person {name: "Max", age: 23}
console.log(p1.sayName()); //Max
console.log(p1.sayAge()); //23
//通过Object.assign()方法一次性向类中添加多个放大 - 只做了解
Object.assign(Person.prototype, {
sayName(){
return this.name;
},
sayAge(){
return this.age;
},
})
上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象
类的继承
使用关键字 extends 来让子类继承父类的方法,然后通过super调用父类中的constructor方法
class Animal {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName() {
return this.name;
}
sayAge() {
return this.age;
}
}
class Dog extends Animal {
constructor(name, age, kind) {
super(name, age); //super是超类的意思,它会去调用父类中的contructor方法
// Animal.call(this, mame, age);
this.kind = kind;
}
//子类自己的方法
sayInfo() {
return `${this.name}已经${this.age}岁了,是条${this.kind}。`
}
//重写父类的方法 - 子类的方法与父类同名就会覆盖父类的方法
sayName() {
return this.name + this.sayAge() + this.kind;
}
}
let dog1 = new Dog('小黄', 4, '秋田犬');
console.log(dog1.sayInfo());//小黄已经4岁了,是条秋田犬。
console.log(dog1.sayName());//小黄4秋田犬
Mixin 混入模式的实现*
摘自阮一峰 - ECMAScript 6 入门 - 只做了解
Mixin 指的是多个对象合成一个新的对象,新对象具有各个组成成员的接口
它的最简单实现如下,c对象是a对象和b对象的合成,具有两者的接口
const a = {
a: 'a'
};
const b = {
b: 'b'
};
const c = {...a, ...b};
下面是一个更完备的实现,将多个类的接口“混入”(mix in)另一个类
代码的mix函数,可以将多个对象合成为一个类,使用的时候,只要继承这个类即可
//声明mix函数,通过调用拷贝函数,来拷贝类的全部属性并返回,用剩余参数来接收不定个数的类来传参
function mix(...mixins) {
class Mix {
constructor() {
for (let mixin of mixins) {
copyProperties(this, new mixin()); // 拷贝实例属性
}
}
}
for (let mixin of mixins) {
copyProperties(Mix, mixin); // 拷贝静态属性
copyProperties(Mix.prototype, mixin.prototype); // 拷贝原型属性
}
return Mix;
}
//声明一个拷贝的函数
function copyProperties(target, source) {
for (let key of Reflect.ownKeys(source)) {
if (key !== 'constructor'
&& key !== 'prototype'
&& key !== 'name'
) {
let desc = Object.getOwnPropertyDescriptor(source, key);
Object.defineProperty(target, key, desc);
}
}
}
//声明一个新的类,来继承并调用mix函数,传入需要混入的类,在mix函数中进行拷贝并接收返回的全部属性
class DistributedEdit extends mix(class1, class2, class3) {
// ...
}
上面代码的mix函数,可以将多个对象合成为一个类。使用的时候,只要继承这个类即可