你不知道的JavaScript----混合对象 ”类“

目录

类的概念

类理论:

类设计模式:

类的机制:

类的继承:

类的多态

混入

显示混入 使用call绑定this

隐式混入


类的概念

类的设计模式:实例化,继承和(相对)多态 

  • 封装:把实现某个功能的代码进行封装处理,后期想实现这个功能 直接调用这个函数即可,低耦合,高内聚
  • 多态:重载:方法名相同,参数类型或者个数不同,这样会认为是多个方法 重写:子类重写父类方法
  • 继承:子类继承父类的方法 ,子类的实例既拥有子类赋予的私有/公有属性方法 也想拥有父类赋予的私有/公有属性方法

类理论:

面向对象编程强调的是数据和操作数据的行为本质上是互相关联的。

类是一个通用的基础,继承是实例化的实例具有类的方法和属性,而实例则是一个独立的个体,有自己独有的东西。多态值的是一个类实际化的多个实例,可以改写这个继承的方法。。

类设计模式:

 类是一种设计模式,有多种高级设计模式建立在面向对象类的基础上:迭代器模式、观察者模式、工厂模式、单例模式等等

  • 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。
  • 观察者模式(有时又被称为发布/订阅模式)是软件设计模式的一种。在此种模式中,一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
  • 工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。
  • 单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例

js实际上没有类,类是一种设计模式,所以可以使用方法来模拟类。

类的机制:

​ 在面向类的语言中,必须将类实例化才可以对抽象化的类进行操作。

  • 类通过复制操作被实例化为对象形式;
  • 类实例是由一个特殊的类方法共造的,这个方法名通常和类名相同,被称为构造函数;

这里提到是复制而不是引用。用构造函数new一个实例,构造函数返回的是对象,这个对象指向创建的这个实例,每new一个实例,相当于创建一个新对象,每个实例直接是相互独立的,这样就明白是复制而不是引用。

class Person {
    name = '';
    // 构造函数
    constructor(name) {
        this.name = name;
    }
    sayName() {
        console.log(this.name);
    }
}
var person = new Person('Lee');
person.sayName();

类的继承:

​ 我们常说子类继承父类,但是用子类DNA是继承父类DNA会更好理解。类通过继承和方法重写实现多态。

  • 多态并不表示子类和父类有关联,子类得到的只是父类的一份副本。类的继承其实就是复制。

  • 在大多数面向类语言中,可以使用super来在子类中引用父类。

  • 但是JS本身并不提供多重继承。

class Father {
    constructor(surname) {
        this.surname = surname;
    }
    saySurname() {
        console.log(this.surname);
    }
}

class Son extends Father {
    constructor(surname, name) {
        super(surname);
        this.name = name;
    }
    sayFullName() {
        console.log(`${this.name} - ${this.surname}`);
    }
}

var son = new Son('Lee', 'Prosper');

console.log(son.surname); // Lee
console.log(son.name); // Prosper

son.saySurname(); // Lee
son.sayFullName(); // Prosper - Lee

类的多态

多态的字面意思就是多种状态,同一操作作用于不同的对象上,可以产生不同的解释和不同的执行结果

class Animal {
    say() {
        console.log('Hello');
    }
    eat() {
        console.log('动物用嘴吃饭-狼吞虎咽!!!');
    }
}

class Person extends Animal {
    eat() {
        super.eat();
        console.log('人用嘴吃饭-斯文的可以了!!!');
    }
}

var person = new Person();

person.say(); // Hello

person.eat(); // 动物用嘴吃饭-狼吞虎咽!!! 人用嘴吃饭-斯文的可以了!!!

混入

混入模式(无论显式还是隐式)可以用来模拟类的复制行为,但是通常会产生丑陋并且脆 弱的语法,比如显式伪多态(OtherObj.methodName.call(this, …)),这会让代码更加难 懂并且难以维护。

  1. 因为JavaScript中只有单继承,当我想要使用其他类的方法,或者说想要增加新的方法,但是又不能够修改自己这个类,更别说其父类了,这个时候就是只能够使用混入了
  2. 混入的本质,还是继承,通过继承当前这个类,创建一个新类返回去

显示混入 使用call绑定this

混合复制

function mixin(sobj,tobj) {
  for(var key in sobj) {
    if(!(key in tobj)) { //什么都不存在的情况下复制
      tobj[key] = sobj[key];
    }
  }
  return tobj;
}


var vehicle = {
  engines: 1,
  ignition: function() {
    console.log("点火器点着了");
  },
  drive: function() {
    this.ignition();
    console.log('发车啦');
  }
}

var car = mixin(vehicle, {
  wheels: 4,
  drive: function() {
    // vehicle.drive();
    //显示绑定 将vehicle.drive绑定到当前this上 this.ignition 调用的就是vehicle里的ignition方法
    vehicle.drive.call(this);
    console.log('轮子开始走了');
  }
})

var a = mixin(vehicle, {})

// vehicle.drive()
car.drive()
// a.drive()

寄生继承

function Vehicle() {
  this.engines = 1;
}

Vehicle.prototype.ignition = function() {
  console.log('打开引擎');
};
Vehicle.prototype.drive = function() {
  this.ignition();
  console.log('开始走');
};

function Car() {
  var car = new Vehicle(); //实例化一个Vehicle对象
  car.wheels = 4; //加入新的属性
  var vehDrive = car.drive; //维持一个函数drive的引用
  car.drive = function() { //重写drive 
    // vehDrive(); 
    vehDrive.call(this); //绑定到当前this
    console.log(this.wheels + '走起~');
  }
  return car;
}

var  aCar = new Car();
aCar.drive();
aCar.ignition();

隐式混入

在构造函数调用或者方法调用中使用call,把某个对象的某个属性绑定进来

a.say()中的赋值操作都会应用在b上而不是a上 

var a = {
    say: function() {
        this.name  = 'zz';
        this.age = '18'
    }
}

var b = {
   say1:function() {
       a.say.call(this) //隐式混入 
   }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值