2020.12.9 12:22
01.类的constructor
当类中没定义constructor的时候
class Cat{
eat(){
console.log(`中午吃了`);
}
}
var c=new Cat();
console.log(c);
运行结果:还是有constructor
- construtor方法是类的默认方法,一个类必须有constructor方法。
- 如果没有显示定义,一个空的constructor方法会被默认添加
- 通过new命令生成实例对象的时候,自动调用该方法
constructor默认返回的是实例对象。完全可以指定返回另外一个对象
class Cat{
constructor(color){
this.color=color;
}
eat(){
console.log(`中午吃了`);
}
}
var c=new Cat('白色');
console.log(c);
console.log(c.color);
指定返回另外一个对象(很少使用但要认识)
相当于创建一个指定的对象,该类中的属性和方法都不可以使用。
class Cat{
constructor(color){//返回一个数组,可以使用数组的方法
return new Array(10,20,30);
this.color=color;
}
eat(){
console.log(`中午吃了`);
}
}
var c=new Cat('白色');
console.log(c);
console.log(c.color);//指定返回另一个对象了
console.log(c instanceof Array);//返回的是一个数组
console.log(c.reverse());//颠倒数组
02.ES6中的继承
- Class之间通过extends关键字实现继承。比在es5中通过原型链实现继承,要清晰和方便。更偏向传统编程语言
//父类
class Animal{
constructor(name,color,price){
this.name=name;
this.color=color;
this.price=price;
}
eat(){
console.log(this.name+'吃了月饼');
}
}
//子类Cat继承自父类Animal
class Cat extends Animal{
constructor(name,color,price,pinzhong){//品种是子类特有的
super(name,color,price);
this.pinzhong=pinzhong;
}
}
var cat1=new Cat('小花','白色',1000,'美短');
console.log(cat1);
cat1.eat();
2.super关键字
- super关键字,它在这里表示父类的构造函数,用来新建父类的this对象
- 子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
- 实例化对象的时候,把实参的值,赋值给了constructor,如果constructor没有该属性传递不过来,直接书写属性会报错
- super必须要放到构造函数this的前面
class Cat extends Animal{
constructor(name,color,pinzhong){//constructor没有price属性
super(name,color,price);//super中写了price
this.pinzhong=pinzhong;
}
}
此写法会报错
super调用父类中的构造函数,再把参数传给父类
class Father{
constructor(name){
// 第三步:最后接收子类传来的参数
this.name = name;
}
run(){
console.log("学会了" + this.name + "的跑步技能")
}
}
class Son extends Father{
constructor(name){
//第二步:调用父类中的构造函数,再把参数传给父类
super(name);
}
}
//第一步:先在子类实例中传参数给子类的构造函数
var sonObj = new Son("Father");
sonObj.run(); //输出结果为 "学会了Father的跑步技能"
super调用父类中的普通函数
class Animal{
constructor(name,color,price){
this.name=name;
this.color=color;
this.price=price
}
eat(){
return '吃了月饼';
}
}
class Cat extends Animal{
constructor(name,color,type){
super(name,color);
this.type=type;
}
name(){
return this.name+super.eat();
}
}
var c1=new Cat('小花','白色','波斯猫');
class BSM extends Cat{
constructor(name,color,type){
super(name,color,type);
}
color(){
console.log(this.color+super.name());
}
}
var b1=new BSM('小猪','银白色','美短');
b1.color();
03.继承相关的一些问题
1.判断子类实例对象的属性是自有还是继承来的
console.log(sonObj.hasOwnProperty('name'));
super
相当于把父级的属性一一复制过来,也就成了自有属性,属性是自有的,不继承
如果父类中有price属性
,子类中constructor和super
中不写price
属性,price
属性存在,但是值是undefined
constructor(name,color,pinzhong){
//父类中有price属性,子类super如果不写price,该属性存在,只是值为undefined
super(name,color);
this.pinzhong=pinzhong;
}
把实参的值,赋值给了constructor
var cat1=new Cat('小花','白色',1999,'美短');
会导致原本赋给price
的1999赋给pinzhong
2.原型链相关问题
原型链:当从一个对象那里调取属性或方法时,如果该对象自身不存在这样的属性或者方法,就会去关联的prorotype那里寻找,如果prototype没有。就会去prototype关联的prototype那里寻找。如果还没有,会一直向上寻找,直到prototype....prototype..为null。从而形成了原型链(根本上来说就是继承)
继承是无限制的,可以有很多层
class Animal{
constructor(name,color,price){
this.name=name;
this.color=color;
this.price=price
}
eat(){
console.log(this.name+'吃了月饼');
}
}
class Cat extends Animal{
constructor(name,color,type){
super(name,color);
this.type=type;
}
}
var c1=new Cat('花花','白色','波斯猫');
class BSM extends Cat{
constructor(){
super();
}
}
var b1=new BSM();
判断父类是否存在于子类的原型链中
console.log(Animal.prototype.isPrototypeOf(c1));
console.log(Animal.prototype.isPrototypeOf(b1));
console.log(Cat.prototype.isPrototypeOf(b1));
原型链的概念在类的继承中生效
3.super
继承为什么要加super?
- 在子类的constructor中必须要有super关键字,如果不写,会报错
- 子类的this关键字根据super方法创建
- 子类实例对象的构建,是基于父类实例进行加工。只有super方法才可以返回父类实例
04.get和set
class Circle{
constructor(){
this.r=10;
}
get acr(){
return Math.PI*this.r*this.r;
}
set acr(){
this.r=value;
}
}
var c=new Circle();
// 调用的是get方法
console.log(c.acr);
// 调用的是set方法
c.acr=1;
console.log(c.acr);
- get方法 获取的值的时候会自动调用 一定要加返回值
- set方法 设置值的时候会自动调用 实参是通过等于号赋值
06.静态方法和私有方法
静态方法:Math.random()
静态属性:Math.PI
class Cat{
static eat(){
console.log('这是静态方法,需要通过类直接调用')
}
}
var c=new Cat();
// c.eat(); 会报错 cat是静态方法
Cat.eat();
Cat.type='XXX';
console.log(Cat.type);
- 类中的方法前面如果加了sataic关键字,该方法就是静态方法
- 静态方法只能通过类名直接调用。
- 静态属性指的是类本身有的属性,通过类名.属性名直接调用。不需要实例化对象调用
- 静态方法和静态属性可以被子类继承
class Bsm extends Cat{
constructor(){
super()
}
}
Bsm.eat();
console.log(Bsm.type);
私有方法
在es6的提案,提到了如果方法名以_
开始,默认只能在类中调用,不能被继承或者被实例对象使用
class Cat{
eat(){
this._food()
}
_food(){
console.log('这是水果');
}
}
var c=new Cat();
c._food();
2020.12.9 15:11