在es6之前没有引入class类,所以在这之前是用构造函数充当了类的概念
但是!!!es6又把类的概念给加回来了,所以以后就可以通过类的方式实现封装、继承和多态,写法更加的简便
构造函数
说明
- 通过new调用的函数叫构造函数
- 构造函数可以构造对象
- 构造函数的函数名一般首字母大写
- 构造函数中的this指向构造函数构造出来的对象
- 构造函数中的方法需声明在构造函数的prototype原型对象中,因为可以把prototype看作一个共享空间,声明在此空间中的所有函数可以被每一个实例对象访问到,以不至于每次构造出来的对象都有一套独有的方法,提高了性能。
案例
function Dog(name, age) {
this.name = name;
this.age = age;
}
Dog.prototype.show = function () {
console.log(`这是${this.age}岁的${this.name}`);
}
let fadou = new Dog('法斗', 3);
let taidi = new Dog('泰迪', 2);
fadou.show(); // 这是3岁的法斗
taidi.show(); // 这是2岁的泰迪
console.log(fadou.show === taidi.show); // 为true,证明了构造对象调用的show是同一个函数(共享)
proto、protoype、constructor的关系
- 构造函数构造出来的对象都有__proto__属性
- __proto__属性指向构造出这个对象的构造函数的prototype
- 构造函数中的prototype有constructor属性,且指向该构造函数
- 构造出来的对象(实例化对象)中有constructor属性,也指向该构造函数
prototype可以看作一个共享空间的原因
构造对象上面的__proto__都指向当前构造函数的prototype,它们指向的地址是一样的,所以声明在prototype上的函数能被所有构造对象访问到!!!
原型链
当访问对象的某个属性时,会先在这个对象的本身属性上查找,如果找不到,则会去__proto__指向的构造函数的prototype原型对象上查找,如果找不到,则再去构造函数的prototype原型对象的__proto__中查找,这样一层一层向上查找就会形成一个链式结构,称为原型链,最终会指向null。
Class
封装
class Dog {
constructor(name, age) { // 通过constructor构造器接收属性值
this.name = name;
this.age = age;
}
// 直接将方法声明在类中
show() {
console.log(`这是${this.age}岁的${this.name}`);
}
}
let fadou = new Dog('法斗', 3);
let taidi = new Dog('泰迪', 2);
fadou.show(); // 这是3岁的法斗
taidi.show(); // 这是2岁的泰迪
继承
顾名思义,继承父级的所有属性和方法,通过关键字extends和super()来实现
// 构造一个金毛的类,并继承Dog
class JinMao extends Dog {
constructor(name, age) {
super(name, age);
}
}
let manTou = new JinMao('馒头', 4);
console.log(manTou.name); // 馒头
console.log(manTou.age); // 4
mantou.show(); // 这是4岁的馒头
多态
侧重于重写从父级继承过来的属性和方法或新增独有的属性和方法
// 构造一个金毛的类,并新增color属性和showColor方法、重写show方法
class JinMao extends Dog {
constructor(name, age, color) {
super(name, age);
this.color = color;
}
showColor() {
console.log(`颜色:${this.color}`);
}
show() {
console.log(`这是${this.age}岁的${this.color}的${this.name}`);
}
}
let manTou = new JinMao('馒头', 4, '金色');
manTou.showColor(); // 颜色:金色
manTou.show(); // 这是4岁的金色的馒头
私有属性(#开头的属性)
#开头的属性为私有属性,不能直接通过实例对象访问,可以通过调用类中的方法访问
class Dog {
name;
#age;
constructor(name, age) {
this.name = name;
this.#age = age;
}
show() {
console.log(`名字${this.name},年龄${this.#age}`);
}
}
const fadou = new Dog('法斗', 3);
console.log(fadou.#age); // 报错
fadou.show(); // 名字法斗,年龄3