前言
Class 为 es6 之后推荐的为了更加体现面向对象思想的一种方式, 但从本质上来说它还是原型链的关系, 也就是语法糖. 而 function 构造函数的方法则是 es6 之前常规的面向对象思想体现的一种方式.
本篇文章涉及的原理较多, 可以结合下列文章:
面向对象思想, 构造函数和原型及两者作用, 原型链以及方法执行顺序
class 本质
在理解 class 本质之前, 我们先根据构造函数的特性:
构造函数具有原型对象 prototype
构造函数中的原型对象 prototype 里有 constructor 指向构造函数本身
构造函数可以通过原型对象添加方法
构造函数创建的实例对象有__ proto __原型指向构造函数的原型对象
那么, 我们利用 class Person{} 创建出来的类, 是否存在这些特征?
由下图可知, 类同样有原型对象 prototype 且 prototype 中的 constructor 同样指向 Person 类, 即证明了 1 和 2 两个论点
Person.prototype
同样的我们继续论证, 添加方法
- Person.prototype.sing=function(){
- console.log("唱歌");
- }
- let person=new Person("cc",20);
由下图, 实例对象中存在__ proto __属性指向构造函数的原型对象且添加了 sing 方法
实例对象__ proto __
因此 class 类与构造函数之间原理是相同的, class 是为了更直观体现出面向对象.
对象设计
- class
- class Person {
- constructor(uname, age) {
- this.uname = uname;
- this.age = age;
- }
- sing(){
- console.log("唱歌");
- }
- }
- let person=new Person("ck",20);
- function
- function Person(uname, age){
- this.uname = uname;
- this.age = age;
- }
- Person.prototype.sing= function(){
- console.log("唱歌");
- }
- let person=new Person("ck",20);
静态方法
PS:Class 内部只有静态方法, 没有静态属性. 如果必须定义则类似于函数定义静态成员变量的方式:
Person.sex="男"
之后通过调用静态成员的方式调用即可.
类的静态方法: 在类中添加 static, 例如:
- static dance(){
- console.log("跳舞");
- }
重点:
如果静态方法包含 this 关键字, 这个 this 指的是类, 而不是实例.
父类的静态方法, 可以被子类继承或子类中用 super 调用.
继承
类的继承实现有 extends 关键字
- class Son extends Person{
- constructor(uname, age) {
- super(uname,age)
- }
- }
此时的 super 方法必须在 constructor 内部的第一行, 即子类的 constructor 方法没有调用 super 之前, 就使用 this 关键字, 结果报错, 而放在 super 方法之后就是正确的.
构造函数的实现继承
- function Son(uname,age){
- Person.call(this,uname,age)
- }
- Son.prototype=new Person();
- let son=new Son("ck",20)
注意构造函数的继承方法则是利用 call,apply 改变指针, 同时子对象 Son 的原型对象 prototype 指向 Person 的实例对象, 于是便与 Person 的原型链连接起来但却独立拥有自己的属性和方法.
来源: http://www.jianshu.com/p/d080ddf71d77