ES6 class类的定义、继承及静态方法

本文详细介绍了ECMAScript 6中Class的定义、继承及静态方法的使用,并对比了ES5与ES6的继承实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ECMAScript6(ES6)标准之class类的定义、继承及静态方法

众所周知,JavaScript中是没有传统类的概念的 
它利用原型链完成继承 
对于当时刚学JavaScript的我来说,一时不好接受 
声明的方式看起来非常奇怪 
不过在我们的ES6中借鉴了很多语言的语法(Python、Java…) 
这其中包括class类的概念 
class不是新结构而是原型链的语法糖


早在ES4的时候,草案中就已经出现了class 
不过ES4由于过于激进,和一系列问题 
被大家抵制 
不过大家现在完全不用担心ES6步ES4的后尘 
(好奇的同学可以看看“传说”中的ES4草案:传送门

类定义

我们先来看看我们一般的原型链方法

function Person(name, age){
    this.name = name;
    this.age = age;
}
Person.prototype.say = function(){
    console.log('my name is ' + this.name + ', ' + this.age + ' years old');
}
var person  = new Person('payen', '19');
person.say(); //my name is payen, 19 years old
  • 下面再看看这个新的一等公民是怎样定义的 

学习过C++或者Java的同学一定会感觉无比亲切 
上面的代码利用ES6的class这样写

class Person {
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
    say(){
        console.log('my name is ' + this.name + ', ' + this.age + ' years old');
    }
}
var person = new Person('payen', '19');
person.say(); //my name is payen, 19 years old
  • 新的class写法让对象原型更加清晰 

更像面向对象的编程语言 
不过还是要注意 
虽然是模仿传统的继承方式 
但是只是语法糖 
仍然使用的是[[prototype]]的委托机制 
(包括后面谈到的继承,子类不会像其他语言一样拷贝父类的东西)

注意事项

这里需要注意的有

  • 定义类方法前面没有function关键字
  • 方法之间不能加“,”逗号
  • 类没有提升行为
  • 类内部定义方法不可枚举

函数是有提升行为的 
所以下面的写法没有问题

foo();
function foo(){
    ...
}
  • 但是类没有 

下面的写法浏览器就会报错

var person = new Person();  //错误
class Person{
    ...
}

类内部定义的方法是不可枚举的 
我们可以用for-in验证

for(var prop in person){
    console.log(prop);
}
  • 我们发现传统原型链打印了name,age,say 

但是使用class方法只打印了name,age

类表达式

类的另一种定义方式就是类表达式 
上面的代码也可以这样写

var demo = class {
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
    say(){
        console.log('my name is ' + this.name + ', ' + this.age + ' years old');
    }
}
console.log(demo);
var person  = new demo('payen', '19');   <-- 注意
person.say(); //my name is payen, 19 years old

类比于我们的函数表达式 
以及函数的name属性

function demo(){};
console.log(demo.name); //demo
var demo = function(){};
console.log(demo.name); //demo
var demo = function foo(){};
console.log(demo.name); //foo
class demo{}
console.log(demo.name); //demo
let demo = class {};
console.log(demo.name); //demo
let demo = class foo{};
console.log(demo.name); //foo
  • 类继承

类之间的继承可以通过extends关键字实现 
先定义一个父类

class Point{
    constructor(x, y){
        this.x = x;
        this.y = y;
    }
    toString(){
        return '点坐标: ' + this.x + ',' + this.y;
    }
}
let fp = new Point(12, 34);
console.log(fp.toString()); //"点坐标: 12,34"
  • 接着是子类的声明
class ColoredPoint extends Point{
    constructor(x, y, color){
        super(x, y);
        this.color = color;
    }
    toString(){
        return this.color + super.toString();
    }
}
let sp = new ColoredPoint(56, 78, '红色');
console.log(sp.toString()); //"红色点坐标: 56,78"
  • 这个子类的构造函数中出现了一个新的关键字super 

没有它的话,就无法继承父类的实例属性 
(子类中有constructor,内部就要有super) 
(子类没有自己的this对象,需要继承父类的this对象再添加东西) 
super指代父类的实例(父类的this对象) 
这里的super(x,y)就是调用父类的构造函数 
super.toString()就是调用父类toString()方法


换成我们ES5的继承大概是这个样子的

function ColoredPoint(x, y) {
    Point.apply(this, [x, y]);
}
ColoredPoint.prototype = Object.create(Point.prototype, {
    toString: function() {
        ...
    }
});
ColoredPoint.prototype.constructor = ColoredPoint;
  • ES5的继承, 

实质是先创造子类的实例对象this 
然后再将父类的方法添加到this上面(Parent.apply(this))

ES6的继承, 
实质是先创造父类的实例对象this(必须先调用super) 
然后再用子类的构造函数修改this

它们的实现机制是不同的

静态方法

类相当于实例中的原型 
所有类中定义的方法都会被实例继承 
如果在类方法前加上static 
就不会被实例继承,而是直接通过类来调用

class Foo{
    static print(){
        return 'hello world';
    }
}
console.log(Foo.print()); //"hello world"
  • 静态方法也可以从super调用 

子类调用父类的static方法也只能在静态函数中调用

class Bar extends Foo{
    static say(){
        return super.print();
    }
}
let b = new Bar();
console.log(Bar.print()); //"hello world"
console.log(Bar.say()); //"hello world"
console.log(b.say()); //报错
<think>好的,我现在要回答用户关于ES6Class继承静态方法处理方式的问题。首先,我需要回忆一下ES6继承机制,特别是静态方法的相关知识。 记得在ES6中,通过extends关键字实现继承,子可以继承的属性和方法,包括静态方法静态方法是使用static关键字定义方法,只能通过本身调用,而不是实例。那静态方法继承时是如何处理的呢? 根据引用[1]和引用[2]的内容,子继承时,静态方法也会被继承。比如父有一个静态方法,子可以直接通过名调用这个方法,无需重新定义。比如父Parent有一个静态方法staticMethod,子Son可以通过Son.staticMethod()调用,这说明静态方法继承到子对象上。 另外,引用[1]提到静态方法可以被子继承,并且子可以覆盖父静态方法。例如,子可以定义同名的静态方法,这样在调用时会使用子自己的实现。不过需要注意的是,如果在子静态方法中需要调用父静态方法,可以使用super关键字,如super.staticMethod()。 还需要注意静态方法中的this指向。在静态方法中,this指向的是本身,而不是实例。所以在子静态方法中,this指向子,而不是父。例如,在子Son的静态方法中,this.name应该是Son,而不是Parent。 有没有特殊情况?比如父静态方法是否会被实例继承?根据ES6的规定,静态方法不会被实例继承,所以子的实例无法调用父静态方法,只能通过子本身调用。例如,如果Son继承Parent的静态方法,那么Son.staticMethod()可以调用,但new Son().staticMethod()会报错。 此外,引用[3]提到关于私有方法的处理,虽然用户的问题是关于静态方法的,但可能需要区分静态方法和私有方法的不同。不过用户的问题主要集中在继承时的静态方法处理,所以这部分可以暂时忽略。 总结一下,ES6静态方法继承时的处理方式是: 1. 子继承静态方法,可以直接通过子调用。 2. 子可以覆盖父静态方法。 3. 在子静态方法中,可以通过super调用父静态方法。 4. 静态方法中的this指向子本身。 需要验证这些结论是否正确。比如,可以编写示例代码: class Parent { static staticMethod() { console.log('Parent static method'); } } class Son extends Parent {} Son.staticMethod(); // 输出Parent static method class Daughter extends Parent { static staticMethod() { super.staticMethod(); console.log('Daughter static method'); } } Daughter.staticMethod(); // 先输出Parent,再Daughter 这样验证后,确实符合上述结论。因此,回答时应包括这些点,并引用提供的资料,如引用[1]提到的静态方法可以被子继承,引用[2]中的extends继承示例。</think>### ES6 Class继承静态方法的处理方式 在ES6继承中,静态方法(由`static`关键字定义)的继承遵循以下规则: 1. **静态方法自动继承** 子通过`extends`关键字继承时,父静态方法会自动被子继承[^1]。例如: ```javascript class Parent { static staticMethod() { console.log('父静态方法'); } } class Son extends Parent {} Son.staticMethod(); // 输出:"父静态方法" ``` 2. **子可覆盖父静态方法** 子可以定义与父同名的静态方法,实现覆盖: ```javascript class Daughter extends Parent { static staticMethod() { console.log('子覆盖后的静态方法'); } } Daughter.staticMethod(); // 输出:"子覆盖后的静态方法" ``` 3. **通过`super`调用父静态方法** 在子静态方法中,可通过`super`调用父静态方法[^1]: ```javascript class Son extends Parent { static staticMethod() { super.staticMethod(); // 调用父方法 console.log('子新增逻辑'); } } Son.staticMethod(); // 输出:"父静态方法" → "子新增逻辑" ``` 4. **静态方法中的`this`指向** 静态方法中的`this`指向当前(子),而非父。例如: ```javascript class Parent { static className() { return this.name; } } class Son extends Parent {} console.log(Son.className()); // 输出:"Son" ``` 5. **静态方法不会被实例继承** 静态方法只能通过名调用,实例无法访问: ```javascript const obj = new Son(); obj.staticMethod(); // 报错:obj.staticMethod is not a function ``` ### 关键区别:ES5 vs ES6 - **ES5继承**:静态方法需手动实现继承(例如通过`Object.assign`)。 - **ES6继承**:静态方法通过`extends`自动继承,逻辑更简洁[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值