javascript中this和super用法

本文详细解析Java中的this与super关键字的使用规则、区别及应用场景,帮助开发者掌握对象指向与继承机制的核心概念。
"this",作为一个特殊的关键字,它的规则如下: 
1。可以表示构造函数传递。this(a,b)表示调用另外一个构造函数。这里面的this就是一个特殊语法,不是变量,没有什么类型。 
2。可以在一个类的非static成员内部使用,表示当前这个对象。此时,this就是一个final的普通变量,它有静态类型,就是这个类C本身;它有动态类型,就是当前这个对象的类型。你可以对它调用成员函数,把它传递给别的函数,等等等等。只要一个C类型的final变量可以出现的地方,它就可以出现。


"super"。它和"this"类似,但是也有不同的地方。 
1。表示调用父类的构造函数。也是一个特殊语法,不是变量,没有什么类型。


2。可以在一个类的非static成员内部使用。比如super.method()。 
但是,注意,这个super.method()只是长得跟some_var.method()一样,一个语法糖而已。实质上,"super"根本不是一个变量。


为什么不是?因为如果是就坏了。java里面有一个金科玉律:任何public非static函数的调用都是多态的。 
所以,如果super是个变量,也指向当前对象,那么,不管super的静态类型是什么super.method()必然调用的是子类的那个版本,而不会是我们期望的,静态地选择父类的那个版本。


所以,你只要把super.xxx看成一个特殊的语法,比如理解为“super::xxx”就好了。


既然super不是一个变量,那么不能把它象一个普通变量那样"==",或者传递给某个函数就看起来很正常了,是么?何况,你其实也用不着它,有this你这些要求就都可以办到了。


3。super的另外一个作用是调用父类的protected函数。只有通过"super"这个魔咒,我们才能操作父类的protected成员,别无它法。
<think>我们正在讨论JavaScript中的super关键字。在JavaScript中,super用于调用父类(超类)的方法,包括构造函数。它的行为与Python中的super()类似,但语法细节有所不同。 核心作用: 1. 在子类的构造函数中,super()必须在使用this之前调用,用于初始化父类的属性。 2. 在子类方法中,super.method()用于调用父类的方法。 使用场景: 1. 继承父类的构造函数:子类构造函数中必须先调用super(),才能使用this。 2. 调用父类方法:当子类重写父类方法时,可以使用super来调用父类的方法,实现扩展而不是完全覆盖。 原理: super关键字在类继承中扮演着重要的角色。它指向当前对象的原型(即父类的prototype)。但是注意,在构造函数中,super()相当于调用父类的构造函数,并将返回的对象绑定到子类的this上。 示例: 1. 在构造函数中使用: ```javascript class Parent { constructor(name) { this.name = name; } } class Child extends Parent { constructor(name, age) { super(name); // 调用父类的constructor(name) this.age = age; } } ``` 2. 在方法中使用: ```javascript class Parent { greet() { console.log(`Hello, I'm ${this.name}`); } } class Child extends Parent { greet() { super.greet(); // 调用父类的greet方法 console.log(`I'm ${this.age} years old.`); } } ``` 注意事项: - 在子类构造函数中,必须先调用super(),才能使用this关键字。否则会抛出引用错误。 - 如果子类没有定义构造函数,那么默认会添加一个构造函数并在其中调用super()。 - 在静态方法中,super指向父类的静态方法。 多重继承? JavaScript本身不支持多重继承(一个类继承多个父类),所以super在单继承链中工作清晰。 深入原理: super并不是一个变量,而是一个关键字。它根据当前执行环境(函数或对象方法)的[[HomeObject]]属性来确定父类。每个方法(非箭头函数)都有一个[[HomeObject]]属性,指向该方法所属的对象。在子类方法中,super.method()会从[[HomeObject]]的原型(即父类的原型)上查找方法。 示例:静态方法中的super ```javascript class Parent { static staticMethod() { return 'Parent static method'; } } class Child extends Parent { static staticMethod() { return super.staticMethod() + ' extended by Child'; } } console.log(Child.staticMethod()); // 输出: "Parent static method extended by Child" ``` 常见错误: 1. 忘记在子类构造函数中调用super()。 2. 在调用super()之前使用this。 与直接调用父类构造函数(如Parent.call(this))的区别? 在ES5中,我们通过Parent.call(this)来继承父类的属性。而在ES6中,使用super()更简洁,并且它内部处理了原型链的建立。 总结: super是ES6中类继承的关键字,用于在子类中访问父类的构造函数方法。它确保了正确的原型链建立,并且遵循了面向对象编程的原则。 相关问题: 1. 在JavaScript中,super关键字在原型链上是如何工作的? 2. 为什么在子类的构造函数中必须先调用super()才能使用this? 3. 在JavaScript中,super关键字可以用于对象字面量吗? 4. 在箭头函数中可以使用super吗?为什么? 5. 如何用ES5的语法模拟super的行为?</think>### JavaScript 中 `super()` 方法详解 在 JavaScript 的面向对象编程中,`super` 是用于访问父类构造函数、方法属性的关键字。其核心作用与使用场景如下: #### 一、核心作用 1. **调用父类构造函数** 在子类构造函数中,`super()` **必须首先调用**才能使用 `this`,用于初始化父类属性[^1]: ```javascript class Parent { constructor(name) { this.name = name; } } class Child extends Parent { constructor(name, age) { super(name); // 必须首先调用 this.age = age; } } ``` 2. **访问父类方法** 当子类重写父类方法时,可通过 `super.method()` 调用父类原始实现: ```javascript class Animal { speak() { return "Animal sound"; } } class Dog extends Animal { speak() { return super.speak() + " → Woof!"; // 扩展父类方法 } } ``` 3. **访问父类属性** 在子类中可直接通过 `super.property` 访问父类属性: ```javascript class Vehicle { constructor() { this.type = "Transport"; } } class Car extends Vehicle { getInfo() { return `Type: ${super.type}`; // 访问父类属性 } } ``` #### 二、使用场景 1. **构造函数链式调用** 确保父类初始化逻辑执行: ```javascript class Rectangle { constructor(height, width) { this.height = height; this.width = width; } } class Square extends Rectangle { constructor(side) { super(side, side); // 调用父类构造 } } ``` 2. **方法扩展而非覆盖** 在子类方法中添加新功能而不破坏父类逻辑: ```javascript class Logger { log(message) { console.log(`[INFO] ${message}`); } } class TimestampLogger extends Logger { log(message) { super.log(`${new Date().toISOString()} ${message}`); } } ``` 3. **静态方法继承** 在静态方法中使用 `super` 调用父类静态方法: ```javascript class MathUtils { static square(x) { return x * x; } } class AdvancedMath extends MathUtils { static cube(x) { return super.square(x) * x; // 调用父类静态方法 } } ``` #### 三、关键原理 1. **原型链机制** `super` 基于原型链查找: - `super()` → 调用父类构造函数(`[[HomeObject]]` 指向父类原型) - `super.method()` → 从父类原型查找方法 2. **执行顺序约束** 在子类构造函数中: - 必须先调用 `super()` 才能使用 `this` - 违反时将报错:`ReferenceError: Must call super constructor...` 3. **与 `this` 的关系** `super()` 隐式绑定当前 `this` 到父类构造函数: ```javascript super(...args); // 等价于 Parent.prototype.constructor.call(this, ...args) ``` #### 四、特殊注意事项 1. **箭头函数中的 `super`** 箭头函数无自己的 `super` 绑定,会继承外层作用域的 `super`: ```javascript class A { method() { return () => super.method(); // 正确继承 } } ``` 2. **对象字面量中的 `super`** 在简写方法中可直接使用: ```javascript const parent = { greet() { return "Hello" } }; const child = { __proto__: parent, greet() { return super.greet() + " World!" } }; ``` 3. **避免递归调用** 错误用法会导致无限递归: ```javascript class Buggy { method() { super.method(); // 错误:父类无此方法将递归查找 } } ``` #### 五、与 ES5 继承对比 | **特性** | `super` (ES6) | ES5 模拟 | |------------------|-----------------------------|--------------------------| | 构造函数调用 | `super(args)` | `Parent.call(this, args)` | | 方法调用 | `super.method()` | `Parent.prototype.method.call(this)` | | 静态方法继承 | 原生支持 | 需手动复制 | | 原型链维护 | 自动处理 | 手动设置 `Child.prototype = Object.create(Parent.prototype)` | > 通过 `super`,JavaScript 实现了更简洁、安全的类继承机制,是面向对象编程的核心特性[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值