面向对象、类与继承

1.类与实例

1.类的声明

1.构造函数声明

function Animal(name,age){
    this.name = name;
    this.age = 20;
}

//给构造函数的原型添加方法,在原型上添加可以进行数据共享、节省内存空间
Animal.prototype.say = function(){
    console.log("我叫"+this.name+",我今年"+this.age+"岁了。")
}

2.ES6中的class声明

class Animal2{
    //可以定义实例属性
    sex = "母"
    //定义静态属性
    static hobby = "吃"

    //构造器
    constructor(name,age){
        this.name = name;
        this.age = age;
    }

    //相当于在原型对象上添加的方法
    say(){
        console.log("我叫"+this.name+",我今年"+this.age+"岁了。");
    }

    //静态方法
    static like(){
        console.log("我喜欢"+Animal2.hobby);
    }
}

var animal2 = new Animal2("dog",20);
animal2.name;
animal2.say();
Animal2.hobby;
Animal2.like();

2.生成实例

var animal = new Animal("dog",20);

var animal2 = new Animal2("dog",20);

2.类与继承

实现继承的几种方式

类的继承的本质就是原型链

1.借助构造函数

缺点:只能继承父类的实例属性,不能继承其原型对象的方法和属性

//父类构造函数
function Parent(name){
    this.name = name;
    this.type = "Parent";
}

//父类添加公共方法
Parent.prototype.say = function(){
    console.log("hello Parent.")
}


//子类构造函数
function Child(msg){
    //借助构造函数实现继承,只能继承父类的实例属性,不能继承其原型对象的方法和属性
    Parent.call(this,"child");
    this.msg = msg;
}

2.借用原型链

缺点:修改了其原型中的引用类型的值,结果其他实例对象中的值也改变了

//父类构造函数
function Parent(name){
    this.name = name;
    this.type = [1,2,3,4,5,6];

}

//父类添加公共方法
Parent.prototype.say = function(){
    console.log("hello Parent.")
}


//子类构造函数
function Child(msg){
    this.msg = msg;
}

//借助原型链实现继承,Child的原型为父类的一个实例
Child.prototype = new Parent();


var child1 = new Child("hello");
var child2 = new Child("world");

//修改了其原型中的引用类型的值,结果其他实例对象中的值也改变了
child2.type.push(7);

3.使用组合方式实现继承

缺点:child.constructor === Parent,而不是Child,无法区分实例到底是由子类创建的还是父类创建的,而且不能修改子类的prototype.constructor,因为修改后父类的prototype.constructor也会修改,指向相同

//父类构造函数
function Parent(name){
    this.name = name;
    this.type = [1,2,3,4,5,6];

}

//父类添加公共方法
Parent.prototype.say = function(){
    console.log("hello Parent.")
}


//子类构造函数
function Child(msg){
    //1.借助构造函数实现继承,继承父类的实例属性和方法
    Parent.call(this,"child");
    this.msg = msg;
}

//2.借助原型链实现继承,Child的原型为父类的原型对象,即它们原型对象的引用相同
Child.prototype = Parent.prototype;


var child1 = new Child("hello");
var child2 = new Child("world");

//此时修改的只是child2的type属性,child1中的type属性没有改变,因为type属性为实例属性
child2.type.push(7);


//false
child1.__proto__.constructor === Child

//true
child1.__proto__.constructor === Parent

升级1:

//父类构造函数
function Parent(name){
    this.name = name;
    this.type = [1,2,3,4,5,6];

}

//父类添加公共方法
Parent.prototype.say = function(){
    console.log("hello Parent.")
}


//子类构造函数
function Child(msg){
    //1.借助构造函数实现继承,继承父类的实例属性和方法
    Parent.call(this,"child");
    this.msg = msg;
}

//2.借助原型链实现继承,Child的原型为一个对象,该对象的原型为父类的原型对象
Child.prototype = Object.create(Parent.prototype);

//赋值原型的constructor为本身
Child.prototype.constructor = Child


var child1 = new Child("hello");
var child2 = new Child("world");

//此时修改的只是child2的type属性,child1中的type属性没有改变,因为type属性为实例属性
child2.type.push(7);


//true
child1.__proto__.constructor === Child

//false
child1.__proto__.constructor === Parent

4.ES6中的继承

class Animal{
    //可以定义实例属性
    sex = "母"
    //定义静态属性
    static hobby = "吃"

    //构造器
    constructor(name){
        this.name = name;
    }

    //相当于在原型对象上添加的方法
    say(){
        console.log("我叫"+this.name+",我今年"+this.age+"岁了。");
    }

    //静态方法
    static like(){
        console.log("我喜欢"+Animal.hobby);
    }
}


//子类
class Dog extends Animal{
    constructor(name,age){
        //必须先调用super(name);否则拿不到this
        //super作为函数使用,代表调用父类的constructor,等价于Animal.prototype.construcor.call(this,name);返回的结果为Dog的实例
        super(name);
        this.age = age;
        //super作为对象使用,设置的属性就是该dog实例的属性
        super.name = "dog";
        //super作为对象使用,如果调用的方法是普通方法,则super代指父类的原型对象
        //等价于Animal.prototype.say.call(this)
        super.say();
    }

    static myLike(){
        //super作为对象使用,如果调用的方法是静态方法,则super代指父类
        //等价于Animal.like.call(this)
        super.like();
    }
}

var dog = new Dog("dog",20);
dog.name;
dog.say();
Dog.hobby;
Dog.myLike();

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值