JavaScript ES6 Class类实现原理详解

作者:小括号时间:2026-10-23 18:05:40浏览:274

本文详细解析JavaScript ES6中Class类的实现原理。从ES5构造函数到ES6语法的演变入手,阐述constructor构造函数的作用,深入讲解extends继承机制及super关键字的使用限制,并分析static静态属性和方法的调用规则与应用场景,帮助开发者掌握面向对象编程的核心概念。

ES6 Class类概述与语法演变

在JavaScript ES6标准发布之前,语言中并不存在Class(类)这一概念。当时,生成实例对象的传统且主要的方式是通过定义构造函数来实现的。

例如:


function Mold(a,b){
         this.a=a;
         this.b=b;
     }
     Mold.prototype.count=function(){
       return this.a+this.b;
     };
     let sum=new Mold(1,2);
    console.log(sum.count())  //3

这种写法与传统面向对象语言存在较大差异,代码结构相对繁杂,可读性较差。

ES6标准引入了更加贴近其他主流面向对象语言的语法,正式引入了Class(类)的概念。类作为对象的模板,允许开发者通过class关键字来定义类,其用法类似于Python、Java等语言。

需要注意的是,ES6中的大部分功能在ES5中均能通过其他方式实现。ES6的class本质上可以看作是一种语法糖,它并未改变JavaScript基于原型的本质,而是提供了更简洁、更清晰的定义类的方式,使其更接近传统的面向对象编程思想。对比上述ES5写法,使用ES6实现相同功能的代码如下:


class Mold{
       constructor(a,b){
         this.a=a;
         this.b=b;
       }
       count(){
         return this.a+this.b;
       }
    }
    let sum=new Mold(1,2);
    console.log(sum.count())  //3

在上述ES6代码中,定义类时只需使用class关键字,且类中的方法无需再使用function关键字进行定义。此外,ES6引入了constructor方法,专门用于定义类的构造逻辑;该方法中的this关键字指向新创建的实例对象。对比前文ES5中的构造函数Mold,它实际上对应于ES6中Mold类的constructor方法。

constructor构造函数的原理

constructor

在ES6中,实例对象的构造函数即为该类本身。当使用new关键字实例化类(如new 类名())时,实际上就是执行了该类的constructor函数。

例如:


class Mold{
       constructor(){
        console.log("aaa")
       }
    }
 let m=new Mold();// aaa
 console.log(m.constructor===Mold);//true

以上代码展示了Mold类的constructor逻辑,在实例化对象时会自动执行默认的constructor方法。

JavaScript中任何对象都拥有构造函数,且该构造函数与当前对象所属的类是一致的。

例如:


let arr=new Array();
 console.log(arr.constructor===Array);//true
 let str=new String();
 console.log(str.constructor===String);//true
 let obj=new Object();
 console.log(obj.constructor===Object);//true

类的继承extends机制

2. 类的继承 extends

子类通过extends关键字继承父类后,将自动获得父类的所有方法和属性,这其中包括静态方法和静态属性。

如果子类在定义时没有显式声明constructor方法,JavaScript引擎会默认为其添加一个空的constructor方法。

因此,任何子类都必然拥有constructor方法。

例如:


//class 类名 extends 被继承的类{}
Class Father{
   constructor(){
   }
   sum(){
     console.log("abc");
   }
   static fn(){
     console.log("hello")
   }
 }
 Class Son extends Father{
  
 }
 let s=new Son();
 s.sum()//abc,继承了父类的sum()方法
 Son.fn()//hello 继承了父类的静态方法fn()

继承后的子类对父类方法的处理通常有三种方式:

1). 完全继承:如果子类不需要修改父类方法的行为,则无需重写该方法,子类执行的方法内容与父类完全相同。

2). 重写覆盖:如果子类需要改变父类方法的逻辑,只需在子类中重新定义该方法即可覆盖继承过来的父类方法。

3). 加工扩展:子类可以使用super关键字调用父类的方法或属性,在此基础上结合子类自身特有的方法和属性进行扩展。

super关键字的使用限制

3. super

在子类中调用父类的构造函数时,直接使用super()即可,并且可以向super传递参数以初始化父类状态。

在子类的构造函数中,必须首先调用super()方法,之后才能使用this关键字。如果在调用super()之前使用this,程序将报错。

例如:


//super.父类函数();
 class Father{
   constructor(){
    console.log("bbb");
   }
 }
 class Son extends Father{
   constructor(x){
    this.x=x;//ReferenceError,报错
    super();
    this.x=x;//正确
   }
 }
 let sum=new Son();//bbb

static静态属性与方法的应用

4. 类的static静态

在类的属性或方法定义前添加static关键字,即可定义类的静态属性和静态方法。

所有的静态属性和静态方法都无法通过实例化的对象进行调用。

静态属性和静态方法必须通过类本身来调用。它们是类的专属成员,与具体的实例化对象无关。常见的例子包括数组工具方法Array.from()和数学方法Math.random()。

例如:


class Mold{
     static x=0;
     y=1;
     static fn1(){
       console.log("aaa")
     }
     fn2(){
       console.log("bbb");
     }
    }
   let m=new Mold();
   console.log(m.x,m.y);//undefined , 1
   m.fn1(); // TypeError 
   m.fn2(); // bbb
   //需要通过类来调用
   Mold.fn1(); //aaa
   console.log(Mold.x);//0

静态成员的主要使用场景包括:

一般静态方法用于解决针对某一类对象的通用问题。

它们处理的是具体类型层面的逻辑,而非针对某个具体对象实例的逻辑。

静态属性通常用于存储该类的一系列通用属性变量。

这种存储机制在类定义加载时即已存在,相当于全局变量,可以在代码的任何位置调用,且不会被自动销毁或回收。

以上就是本文关于JavaScript ES6 Class类实现原理的全部内容,希望对大家的学习有所帮助,也欢迎大家继续支持本站。

作者最新文章