JS中的面向对象,在es6中有class
类后,变得更容易理解了,虽然这个class
只是JS原型思想构造函数的语法糖,但无疑让习惯了面向对象编程的开发者找到熟悉的套路。
JS中的构造函数:
1function People(name, age){
2 this.name = name;
3 this.age = age;
4}
5People.prototype.eat = function(){
6 console.log([this.name, 'eat somthine'].join(' '))
7}
8People.prototype.speak = function(){
9 console.log('My name is '+this.name+', age '+this.age)
10}
将构造函数改写成类时的写法,类作为对象的模板:
1//People类
2class People {
3 constructor(name, age){
4 this.name = name;
5 this.age = age;
6 }
7
8 eat(){
9 console.log(`${this.name} eat somthing.`);
10 }
11
12 speak(){
13 console.log(`My name is ${this.name}, age ${this.age}`);
14 }
15}
16
17//类实例化
18let nitx = new People('nitx', 30);
19let sxm = new People('sxm', 31);
20
21nitx.eat();
22nitx.speak();
23
24sxm.eat();
25sxm.speak();
26
27/*
28打印:
29nitx eat somthing.
30My name is nitx, age 30
31sxm eat somthing.
32My name is sxm, age 31
33*/
上例People
类中的constructor
是构造方法,对应原来的构造函数,类的this
和构造函数中的this
一样代表实例对象。People
类中的实例方法无需加上function
关键字,直接定义函数名和函数体即可,方法之间不需要用逗号隔开。
1typeof People; //function
2People === People.prototype.constructor; //true
上例代码表明类的数据就是函数,类本身就指向构造函数。在类的实例上调用方法,其实就是调用原型上的方法。
由于类的实例方法都是定义在prototype
属性上的,所以People
类的实例方法也可以使用Object.assign
方法来一次性添加多个实例方法。
1class People {
2 constructor(){
3 // ...
4 }
5}
6Object.assign(People.prototype, {
7 eat(){
8 console.log(`${this.name} eat somthing.`);
9 },
10 speak(){
11 console.log(`My name is ${this.name}, age ${this.age}`);
12 }
13})
此外需要注意一点,类中创建的实例方法都是不可枚举的,而构造函数创建的实例方法则是可枚举的,这点需要注意。
还有几个注意点总结如下:
class
类和模块内部默认遵循严格模式。class
类默认就有constructor
方法,即使在创建时没有在类中写有constructor
,JS引擎也会自动添加。constructor
默认返回实例对象,即this
,也可手动更改返回的对象。class
类调用必须使用new
关键字,否则会报语法错误。class
类实例的属性除非显示定义在其本身(即this
对象),否则都是定义在原型上的。class
类的所有实例共享同一个原型,所以当在某个实例对象上通过使用Object.getPrototypeOf
获取该实例原型的方法来在原型上添加新的方法时,其他该类的实例对象也自动拥有新增的原型方法。class
类也可以用表达式来定义:命名类表达式和匿名类表达式。和命名函数表达式一样,这个命名只在类内部才能使用。而匿名类表达式和匿名函数表达式一样,可以写出立即执行的类,写法同立即执行匿名函数表达式。class
不存在变量提升这个机制。