ES6中构造函数内super关键字的使用

本文探讨了在ES6中使用构造函数和super关键字进行继承时的场景。子类构造函数必须调用super()以初始化继承自父类的this对象。super在这里代表父类的构造函数,但它返回的是子类的实例。通过super可以访问和操作父类的属性和方法:super.xxx等于父类.prototype.xxx,super.xxx()等于父类.prototype.xxx(),而super.xxx=xxx等同于this.xxx=xxx。

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

起因: 平时在写react组件或者是class时经常会写一个 super(),但是一直都没有深入了解这个super到底干了什么,今天抽空了解了一下,做一下记录

场景

1.在ES6实现继承中会有constructor构造函数,而实现继承的子类构造函数中必须先调用super()方法,此处的super()为父类的构造方法,而如果不调用,浏览器则会报错,比如:

class Person {
	    constructor(name,age){
		    this.name = name;
		    this.age = age;
		}
}
class Son extends Person {
	    constructor(name,age,cc){
	    	// super(name,age) 正确写法
		    console.log(cc)
		}
}
let newSon = new Son(123,456,777)

把如上代码复制进浏览器,我们会得到一串报错

Uncaught ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
    at new b (<anonymous>:3:13)
    at <anonymous>:1:11

理解一下报错应该就是说,因为子类没有自己的 this 对象,而是继承父类的 this 对象,然后对其进行加工,而 super 就代表了父类的构造函数。super 虽然代表了父类 Person的构造函数,但是返回的是子类 Son 的实例,即 super 内部的 this 指的是 Son。

下面是比较完整的解释:

class Person {
	constructor(name,age){
		this.name=name;
		this.age=age;
		this.pname='我是父类';
	}
	say(){
		console.log(this.name,this.age);
	}
	test(){
		console.log('我是父类的test方法');
	}
}
Person.prototype.pname='我是父类的原型上的pname';
class Son extends Person{
	constructor(name,age){
		super(name,age);
		this.pname='我是子类';
	}
	test(){
		console.log('我是子类的test方法')
		console.log(super.pname);
		
		//打印出 : 我是父类的原型上的pname   
		可得出结论 在子类中使用super.xxx变量时此时 都是访问 父类原型上的属性。
		
		console.log(super.test());   
		
		 //  打印出 :我是父类的test方法   
		 
		 可得出结论  在子类中super.xxx();  调用方法都是调用父类中的方法,
		 
		 其实 console.log(Person.prototype.test)  试着打印出原型上的test方法你会发现就是父类中定义的test方法。
		 
		 所以综合上述结论可得出  使用super.xxx, super.xxx(); 访问属性和调用方法时都是在父类的原型上去查找
		 
		 。而且如果父类没有不会找子类的,而是直接打印出undefined.
		 
		 
		 super.pname="修改pname的值";
		 console.log(this.pname);//访问子类本身的pname;       结果: 修改pname的值
		 console.log(super.pname);//访问父类原型上的pname;     结果:我是父类的原型上的pname
		 console.log(new Person().pname);// 访问 父类上的pname;  结果: 我是父类
	
		结论:发现改变的是子类上的pname 值
		
		所以可以得出结论:
		
		当使用	super.xxx=xxx;进行为属性赋值时,此时super===this,访问的是子类
	}
}
let  son=new Son('张三',18); 

综上所述:
console.log(super.xxx) 等于 console.log(父类.prototype.xxx);
console.log(super.xxx()) 等于 console.log(父类.prototype.xxx());
super.xxx=xxx 等于 this.xxx=xxx;

参考链接:https://blog.youkuaiyun.com/qq_41709082/article/details/86573720

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值