class

... 2022-12-19 About 2 min

# class

之前就说过,在其他语言中比如java,php都会用class来做面向对象,但es5就没有使用原型和构造方法来实现的,这样就是真的没有标准了,每个人的写法都可以不一样,而且每个人都没有错误,这对项目团队的研发来讲,老好玩了

说class和面向对象之前先简单的看一下语言的发展史

机器语言 -> 汇编语言 -> 低级语言(底层语言,面向过程 eg:C) -> 高级语言(面向对象) -> 模块系统 -> 框架 -> 系统接口(API)

# ES5的面向对象

ES5面向对象---只能算是半面向对象

function Person (name,age) {
  this.name = name
  this.age = age
}
Person.prototype.showName = function () {
  console.log(this.name)
}
Person.prototype.showAge = function () {
  console.log(this.age)
}
function Worker(name,age,job) {
  Person.call(this,name,age)
  this.job = job
}

Worker.prototype = Object(Person.prototype)
Worker.prototype.constructor = Worker

Worker.prototype.showJob = function () {
  console.log(this.job)
}

let person = new Person('liaoxuan', 12)
person.showName()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# ES6的面向对象

class Person { // 类声明
  constructor (name, age) { // 构造函数
    this.name = name
    this.age = age
  }
  static self(){ // 不会被实例继承,实例没有此方法 但是可以被继承
    this._static = 'test' // 这里的this始终指向类,不会指向实例
  }
  showName () {
    console.log(this.name)
  }
  shoeAge () {
    console.log(this.age)
  }
}

class Worker extends Person { // 继承
  constructor (name, age, job) {
    super(name,age) // 父类/超类
    this.job = job
  }
  showJob () {
    console.log(this.job)
  }
}
let worker = new Worker('liaoxuan', 23 , 'net worker')
worker.shoeAge()
worker.showName()
worker.showJob()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

两个比较:ES6的好处

  1. 省事,有标准
  2. 便于扩展

# 还是总结一下吧,ES5/ES6的继承,除了写法上面,还有其他什么的区别?

  1. class声明会提升,但是不会初始化赋值
const foo = new Foo() // ReferenceError: Foo is not defined
class Foo {
  constructor() {
    this.foo = 42;
  }
}
1
2
3
4
5
6
  1. class声明内部会启用严格模式
function Bar() {
  baz = 42; // it's ok
}
const bar = new Bar();

class Foo {
  constructor() {
    fol = 42; // ReferenceError: fol is not defined
  }
}
const foo = new Foo();
1
2
3
4
5
6
7
8
9
10
11
  1. class的所有方法都是不可枚举的
function Bar() {
  this.bar = 42;
}
Bar.answer = function() {
  return 42;
};
Bar.prototype.print = function() {
  console.log(this.bar);
};
const barKeys = Object.keys(Bar); // ['answer']
const barProtoKeys = Object.keys(Bar.prototype); // ['print']


class Foo {
  constructor() {
    this.foo = 42;
  }
  static answer() {
    return 42;
  }
  print() {
    console.log(this.foo);
  }
}
const fooKeys = Object.keys(Foo); // []
const fooProtoKeys = Object.keys(Foo.prototype); // []
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  1. class 的所有方法(包括静态方法和实例方法)都没有原型对象 prototype,所以也没有[[construct]],不能使用 new 来调用。
function Bar() {
  this.bar = 42;
}
Bar.prototype.print = function() {
  console.log(this.bar);
};

const bar = new Bar();
const barPrint = new bar.print(); // it's ok

class Foo {
  constructor() {
    this.foo = 42;
  }
  print() {
    console.log(this.foo);
  }
}
const foo = new Foo();
const fooPrint = new foo.print(); // TypeError: foo.print is not a constructor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  1. 必须使用new关键字调用class

  2. class 内部无法重写类名

function Bar() {
  Bar = 'Baz'; // it's ok 但是没什么卵用,下面也是不能够使用new Bax(), 不要天真的一位是可以的
  this.bar = 42;
}
const bar = new Bar();
// Bar: 'Baz'
// bar: Bar {bar: 42}  

class Foo {
  constructor() {
    this.foo = 42;
    Foo = 'Fol'; // TypeError: Assignment to constant variable
  }
}
const foo = new Foo();
Foo = 'Fol'; // it's ok 这个地方就彻底的赋值了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Last update: December 19, 2022 11:58
Contributors: salvatoreliaoxuan