ES5中实现类
构造函数法
function Person(name,age){
this.name = name;
this.age = age;
this.say = function (){
console.log(`${this.name} + ${this.age}`)
}
}
zs = new Person('张三',12);
zs.say();// 张三12
console.log(zs.name); // 张三
优点:遇到new出来的每个实例都有一份属于自身的数据
缺点:在定义函数时,内存造成很大浪费
原型对象法
function Person (){}
Person.prototype.name = '张三';
Person.prototype.age = '张三';
Person.prototype.say = function (){
console.log(`${this.name}+ ${this.age}`)
}
let zs = new Person('张三',12);
zs.say();
console.log(zs.name);//张三
优点:共用一个类的方法,节省大量的存储空间 缺点:所有实例公用一份数据,数据赋值和使用比较麻烦
构造函数 + 原型对象法
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype.say = function(){
console.log(`${this.name}`)
}
优点:结合上两种方法
ES6 Class实现类
基本语法
// 类声明
class Person {}
// 类表达式
var Student = class{}
类的构造函数
通过类的构造方法constructor创建实例时向类传递参数,一个类只有一个构造函数
class Person {
constructor(name,age) {
this.name = name;
this.age = age;
}
}
var p = new Person('张三',12)
console.log(p) ;// Person{name:'张三',age:12}
类的实例方法
class Person {
constructor(name,age){
this.name = name;
this.age = age;
}
running(){
console.log(`${this.name} is running`)
}
}
var p = new Person('张三',12)
p.running()
类的访问器方法
class Person {
constructor(name){
this.name = name;
}
// 类的访问器方法
get name(){
return this._name
}
set name(val){
this._name = val
}
}
const p = new Person('张三')
通过getter、setter访问器函数,可以对读写进行拦截操作。
类的静态方法
静态方法:类独有,实例没有,通过static关键字来描述一个类中的一个方法为静态方法。
class Person {
constructor(name){
this._name = name;
}
static greeting(){
console.log(`nihao`)
}
}
const p = new Person('张三')
Person.greeting() // 成功
p.greeting() // 报错,没有此方法
类的静态属性
静态属性指的是Class本身的属性,即Class.propName,而不是定义在实例对象(this)上的属性。
// 旧写法
class Foo {}
Foo.prop = 1;
Foo.prop // 1
// 新写法
class Foo{
static prop = 1
constructor(){
console.log(Foo.prop) // 1
}
}
// 类的静态属性只要在上面的实例属性写法前面,加上static关键字就可以了。
实现继承
class Person {
constructor(name) {
this.name = name
}
running(){
console.log(`${this.name} is running`)
}
}
// extends 关键字继承父类
class Student extends Person {
constructor(name,sno){
// super 调用父类的构造函数
// 传入自定义参数
super(name)
this.sno = sno
}
studying(){
console.log(`${this.name} is studying`)
}
}
const s1 = new Student('张三',1212);
s1.running() // 张三 is running
s1.studying() 张三 is studying
类的实例属性
类的实例属性可以用等式,写入类的定义之中。
Class Foo(){
prop = 1
constructor(){
console.log(this.prop) // 1
}
}
Class静态方法
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
class Foo {
static classMethod() {
return 'hello';
}
}
Foo.classMethod() // 'hello'
var foo = new Foo();
foo.classMethod() // TypeError: foo.classMethod is not a function
如果静态方法包含this关键字,这个this指的是类,而不是实例。
class Foo {
static bar () {
this.baz();
}
static baz () {
console.log('hello');
}
baz () {
console.log('world');
}
}
Foo.bar() // hello
父类的静态方法,可以被子类继承
class Foo {
static classMethod() {
return 'hello';
}
}
class Bar extends Foo {
}
Bar.classMethod() // 'hello'
静态方法也是可以从super对象上调用的
class Foo {
static classMethod() {
return 'hello';
}
}
class Bar extends Foo {
static classMethod() {
return super.classMethod() + ', too';
}
}
Bar.classMethod() // "hello, too"
ES6中class类继承与ES5继承的区别
- ES5的继承实质是先创建子类的实例对象,然后再将父类的方法添加到this上
- ES6的继承,实质是先创建父类的实例对象this(先调用父类的super()方法),再用子类的构造函数修改this。
具体的:ES6通过class关键字定义类,里面有构造方法,类之间通过extends关键字实现继承。子类必须再constructor方法中调用super方法。