美文网首页
类与继承

类与继承

作者: della岳 | 来源:发表于2022-01-27 13:52 被阅读0次

一、es5的类与继承

1. prototype原型对象

每个函数(普通函数、构造函数)都有一个prototype原型对象,每个prototype都有constructor属性,constructor指向函数本身
每个实例都有一个proto,指向构造函数的原型对象

function getSum(a,b){
    console.log(a+b)
}
function People(name,age){
    this.name = name;
    this.age = age;
}
getSum(1,2);
console.log(People.prototype.constructor)// People
console.log(getSum.prototype.constructor)// getSum
2. 静态方法和实例方法

① 在构造函数体中,this指向实例对象,通过this创建的属性属于实例属性
② 在构造函数原型对象上创建方法,方法内部this指向实例对象,属于实例方法
③ 直接挂在构造函数上的属性为静态属性、方法为静态方法,静态方法内的this指向构造函数本身
④ 直接调用构造函数,函数体内this指向调用时所处的作用域,即window

// 声明构造函数People
function People(name,age){
    console.log(this);// this指向实例对象
    this.name = name; //① 实例属性
    this.age = age; //① 实例属性
    People.count++;
}
// ② 实例方法,构造函数原型对象上的方法属于实例方法
People.prototype.showName = function(){
    console.log('我的名字是',this.name)
}
// ③ 静态属性,构造函数上的属性属于静态属性
People.count = 0;
// ③ 静态方法,构造函数上的方法属于静态方法
People.getCount = function(){ 
    console.log(this);// this指向构造函数本身
    console.log(this.count === People.count)//true ,此处等同于People
    console.log('目前共有',People.count,'个人')
}

let p1 = new People('xiaoyue1')
console.log(p1);
p1.showName();// 每个实例都能访问到原型对象上的方法和属性
let p2 = new People('xiaoyue2')
console.log(p2);
p2.showName();// 每个实例都能访问到原型对象上的方法和属性

console.log(People.count) //访问静态属性
People.getCount(); //调用静态方法
People('lily',18); // ④ 直接调用构造函数,函数题内部this指向当前作用域window

// 常见静态方法和属性
Math.max(1,2)
Math.PI
console.log(Math)// 查看Math上有哪些静态睡醒和静态方法
// 常见实例方法和属性
let arr = [1,2,3];
console.log(arr.slice(1))// slice为实例方法,slice、push、pop等这些方法都是挂在Array的构造函数上的
3. 类的继承,组合式继承

① 继承父类的属性:通过调用父类函数,call改变函数内this指向。People.call(this,name)
② 继承父类的方法:实例化一个父类的对象赋值给子类的原型对象,让子类实例通过自身的原型对象访问到父类的原型对象的方法。Student.prototype = new People();
③ 原型对象的constructor指回子类。Student.prototype.constructor = Student;

function Student(name,hobby){
    People.call(this,name);//① 继承属性:执行People函数,改变this指向为当前Student实例
    this.hobby = hobby; //实例自身属性
}
// ②实例化一个People对象peo,peo赋值给Student原型对象,实例对象peo能访问到People原型对象上所有的方法, 因此Student原型对象也能访问到People原型对象上的所有方法。
const peo = new People(); //实例化一个People对象peo
Student.prototype = peo; //赋值给Student原型对象
// Student.prototype = new People(); 或直接这样写
// ③赋值前,Student的prototype的constructor指向Student。
// ③赋值后,实例对象peo本身没有constructor,就会去new出它的构造函数People的原型对象上去找,但People的原型对象的constructor属性是指向People本身的。因此Student.prototype.constructor就会是People,得改回来,让它指回Student,如下。
Student.prototype.constructor = Student; //③
// 除了能访问到People的所有方法,还可以给Student原型对象添加属于自己的方法dance
Student.prototype.dance = function(){ 
    console.log('dance')
}
let s1 = new Student('yoyo','跳舞');
// console.log(Student.count) //undefined,继承不到静态属性和方法
// console.log(Student.getCount()) //报错, 继承不到静态属性和方法
console.log(s1)
s1.showName()
s1.dance()

练习题

console.log(s1.constructor === Student); //true
console.log(s1.constructor === People); //false
console.log(p1.constructor === People); //true
console.log(p1.__proto__ === People.prototype); //true
console.log(s1.__proto__ === Student.prototype); //true
console.log(s1.__proto__.constructor === Student); //true

二、es6的类与继承

1. 类

① class 声明类
② constructor 函数体
③ static 声明静态方法,不能声明静态属性
④ set和get 实例属性声明的另一种方式,可用于属性的读与写时的拦截处理

class People{ //①
    constructor(name){ //②函数体
        this.name = name; //实例属性
        this._sex = 0;
    }
    showName(){ //实例方法
        console.log(this.name)
    }
    // static count = 0; //会报错,es6还不支持这种static声明静态属性的写法!
    static getCount(){ //③静态方法
        // console.log(this) //静态方法this指向People,就是调用getCount时的.前面的那个对象
        console.log(this.count) //0
        console.log(this.count === People.count) //true
    }
    get sex(){ //④getter获取 
        if(this._sex === 0){
            return 'female'
        }else if(this._sex === 1){
            return 'male'
        }else{
            return 'error'
        }
    }
    set sex(val){ //④setter设置,只声明了set没声明get方法,设置时会报错
        if(val ===0 || val === 1){
            this._sex = val;
        }
    }
}
People.count = 0; //静态属性,目前只能这声明
let p1 = new People('yoyo');
console.log(p1);
console.log(p1.sex)
p1.sex = 1;
console.log(p1.sex)
2. 继承

extends继承内容:实例属性、实例方法、静态属性、静态方法、get/set属性

class Student extends People{
    constructor(name,hobby){
        super(name)
        this.hobby = hobby
    }
    study(){
        console.log('study')
    }
}
let s1 = new Student('yoyo','dance');
console.log(s1) 
console.log(s1.sex) //0 继承了get 和set声明的属性
s1.showName(); //继承了实例方法
console.log(Student.count) //0 继承了静态属性
console.log(Student.getCount()) //true 继承了静态方法

相关文章

  • JAVA(9)继承与多态

    继承与多态 、抽象类、接口 继承: 继承是类与类的一种关系 java中的继承是单继承 继承的好处: 子类拥有父类的...

  • 继承与派生

    1,父类与子类,单继承与多继承 2、为何要用继承:用来解决类与类之间代码冗余问题 3,如何实现继承 4,属性查找 ...

  • js面向对象总结

    1、类与实例 类的声明 实例化 2、类与继承 继承的几种方式

  • 继承

    继承:类与类之间的一种关系,子类可以继承父类的成员 关键字extends:继承关键字,使类与类之间产生继承关系 格...

  • OC之02面向对象03之三大特性02继承、多态

    继承 基本使用: 继承用于类与类之间例如:类A 类B 如果说类B继承类A那么,类B就会继承了类A的所有的属性而且...

  • 03.接口和类之间的各种关系

    接口和类的关系 A:类与类之间:继承关系,一个类只能直接继承一个父类,但是支持多重继承 B:类与接口之间:只有实现...

  • 类关系

    六种关系继承与实现关系:类B继承类A或者接口A,就称为继承与实现关系。依赖关系:类B独立模型,类A中方法用到类B,...

  • JS面向对象

    类与实例 创建类 实例化 类与继承 实现继承的几种方式 方式一:利用构造函数进行继承 但是这种方法缺点是无法继承父...

  • 面向对象类

    类与实例 类的声明 ES5 ES6 生成实例 类与继承 如何实现继承 继承的几种方式 原型链是实现继承的主要方法 ...

  • Python所学----python高级(中)

    一. 单继承 、多继承、多态,重写与父类 1.单继承、就是子类继承父类的属性与方法 2.多继承、就是子类继承多个父...

网友评论

      本文标题:类与继承

      本文链接:https://www.haomeiwen.com/subject/daqahrtx.html