Javascript 面向对象编程(一)

214 阅读3分钟

目的

  1. 什么是面向对象编程
  2. 复习关键字new并且理解它所做的四件事
  3. 在我们的代码中使用构造函数来优化我们得代码
  4. 使用call和apply来重构构造函数

面向对象编程的定义

  1. 基于对象概念的编程模式
  2. 这些对象是由类创建的,我们可以把类想象成一个蓝图,把这些对象叫做类的实例
  3. 尽量让类抽象化和模块化

JavaScript中的面向对象编程

JavaScript 中没有内置的类,但是我们可以用函数和对象去模拟

1. 创建对象

想象我们要创建一些house对象,他们都有 bedrooms, bathrooms, numSqft 属性

var house = {
  bedrooms: 2,
  bathroom: 2,
  sqFeet: 1000
}

var house1 = {
  bedrooms: 2,
  bathroom: 2,
  sqFeet: 1000
}

var house2= {
  bedrooms: 2,
  bathroom: 2,
  sqFeet: 1000
}
// 想象一下 我们如果有 1000个房子

解决办法 创建一个函数来构建这些类似的“房子”对象,而不是创建无数个不同的对象

1.构造函数

让我们使用一个函数作为每个房子应该是什么的蓝图——我们把这些函数称为“构造函数”

  function House(bedrooms, bathrooms, numSqft){
    this.bedrooms = bedrooms
    this.bathrooms = bathrooms
    this.numSqft = numSqft
  }

注意一些事:

  • 函数名的大小写
  • 关键字this!!!
  • 我们将属性附加到关键字“this”上。我们希望关键字“this”指的是我们将从构造函数函数中创建的对象,我们该如何做呢?

2.使用构造函数创建对象

  function House(bedrooms,bathrooms,numSqft) {
    this.bedrooms = bedrooms
    this.batnrooms = bathrooms
    this.numSqft = numSqft
  }
  // test
  var firstHouse = Houes(2,2,1000)
  firstHouse //undefined ....

为什么不起作用!!

  • 我们没有从函数中返回任何东西所以我们的House函数返回没有定义的
  • 我们没有显式地绑定关键字'this'或将它放在声明的对象中。这意味着关键字“This”的值将是全局对象,这不是我们想要的!

解决办法 使用关键字new

  function House(bedrooms,bathrooms,numSqft) {
    this.bedrooms = bedrooms
    this.batnrooms = bathrooms
    this.numSqft = numSqft
  }
  // test
  var firstHouse = new House(2,2,1000);
  firstHouse.bedrooms; // 2
  firstHouse.bathrooms; // 2
  firstHouse.numSqft; // 1000

思考关键字new做了什么

  • 首先, 关键字new创建了一个新的空对象
  • 然后,它把关键字this设置到了这个空对象上
  • 添加一条 ‘return this’ 在函数的末尾
  • 执行原型连接操作 {它将一个属性添加到名为“proto”的空对象上,这个空对象将构造函数上的prototype属性链接到空对象上(后面会详细介绍)}

练习 为Dog创建一个构造函数,每个Dog都有姓名(name),年龄(age)属性, 还有bark方法

  function Dog(name, age) {
     this.name = name;
     this.age = age;
     this.bark = function() {
       console.log(this.name + ' 汪汪汪')
     }
  }

  // test 
  var dog1 = new Dog("小黄",1)
  var dog2 = new Dog("小美",2)

  dog1.bark() // 小黄 汪汪汪
  dog2.bark() // 小美 汪汪汪

3.多个构造函数

分别为 Car 和 Motorcycle 创建一个构造函数

  function Car(make, model, year) {
    this.make = make;
    this.model = model;
    this.year = year;
    this.numWheels = 4
  }
  function Motorcycle(make, model, year) {
    this.make = make;
    this.model = model;
    this.year = year;
    this.numWheels = 2
  }

摩托车的功能有重复。有没有办法“借用”汽车功能并在摩托车功能中调用它? 使call/apply

  function Car(make, model, year){
    this.make = make;
    this.model = model;
    this.year = year;
    this.numWheels = 4;
  }
  function Motorcycle(make, model, year){
    //using call
    Car.call(this, make, model, year)
    this.numWheels = 2
  }
  function Motorcycle(make, model, year){
    // using apply
    Car.apply(this, [make,model,year]);
    this.numWheels = 2;
  }

  function Motorcycle(){ 
     // 我们甚至不需要传递参数!
      // 更好的用法是使用apply和arguments
      Car.apply(this, arguments);
      this.numWheels = 2;
  }

小结一下

  • 面向对象编程是一种基于对象被一种蓝图构建的模式,我们使用面向对象写更多模块化和可共享的代码
  • 在支持OOP的语言中,我们将这些蓝图称为“类”,而从它们创建的对象称为“实例”
  • 由于我们在JavaScript中没有内置的类支持,所以我们使用函数来模拟类。这些构造函数通过使用new关键字创建对象
  • 我们可以通过call或apply来避免多个构造函数中的重复