面向对象

79 阅读4分钟

面向对象不是语法,是一种编程思想
面朝过程:关注过程的编程模式
面朝对象:关注对象的编程模式
在面向过程的时候,我们要关注每一个元素,每一个元素之间的关系
在面向对象的时候,我们要关注的就是找到一个对象来帮助我们做这个事情,我等待结果

创建对象的方式

面向对象就是一个找到对象的过程,所以我们需要先创建一个对象

  1. 字面量创建对象
const obj = {} 
obj.name = "YYJ"
  1. 内置构造函数创建对象
const obj = new Object()   
obj.name = "YYJ"
  1. 使用工厂函数的方式创建对象
    这个工厂函数内可以创造出来一个对象,并且给对象添加一些书写那个,还能把对象返回
    使用这个工厂函数创造对象
function createObj() {
    // 手动创建对象  
    const obj = new Object()
    // 手动向对象中添加成员 
    obj.name = "YYJ"
    obj.age = 18
    // 手动返回一个对象  
    return obj
}
// 使用工厂函数创建对象 
const o1 = createObj()
const o2 = createObj()
  1. 使用自定义构造函数创建对象
    工厂函数需要经历三个步骤

手动创建对象
手动添加成员
手动返回函数

构造函数会比工厂函数简单一些

自动创建对象
手动添加成员
自动返回对象

先写一个构造函数
在构造函数内向对象添加一些成员
使用这个构造函数创建一个对象(和 new 连用)
构造函数可以创建对象,并且创建一个带有属性和方法的对象
面向对象就是要想办法找到一个有属性和方法的对象
面向对象就是我们自己制造构造函数的过程

// 先写一个构造函数   
function Person(name, gender) {
    // 在构造函数内向对象添加一些成员  
    this.age = 18
    this.name = name
    this.gender = gender
}
// 使用这个构造函数创建一个对象(和 new 连用)
const p1 = new Person("Jack", "man")
const p2 = new Person("Rose", "woman")

构造函数的基本使用

和普通函数一样,只不过调用的时候要和 new 连用不然就是一个普通函数调用
我们将 new 关键字与 Person 结合的时候叫做实例化
我们调用完毕后会得到一个对象,这个对象叫做实例化对象

  1. 不写 new 的时候就是普通函数调用,没有创造对象的能力
function Person() {}
const o1 = new Person()       // 一个对象 
const o2 = Person()           // 什么也得不到,就是一个普通函数的调用
  1. 首字母不大写,只要和 new 连用,就有创造对象的能力
function person() {}
const o1 = new person()      // 一个对象
  1. 当调用的时候,如果不需要传递参数可以不写 (),但是建议写上
function person() {}
const o1 = new person        // 一个对象
  1. 构造函数内部的 this,由于和 new 连用的关系,是指向当前实例对象的
function Person() {
    console.log(this)
}
const o1 = new Person()       // this ---> o1
const o2 = new Person()       // this ---> o2
  1. 因为构造函数会自动返回一个对象,所以构造函数内部不要写 return
    • return 一个基本数据类型,写了没意义
    • return 一个引用数据类型,那么构造函数本身的意义就没有了

构造函数的缺点

我们使用构造函数的时候,可以通过代码和内容来向当前的对象添加一些内容

function Person() {
    this.name = "Jack"
    this.age = 18
    this.sayHi = function () {
        console.log("hello world")
    }
}
// 第一次 new 的时候,Person 这个函数要执行一边 
// 执行一边就会创造一个新的函数,并且把函数地址赋值给 this.sayHi
const o1 = new Person()
// 第二次 new 的时候,Person 这个函数要执行一边 
// 执行一边就会创造一个新的函数,并且把函数地址赋值给 this.sayHi
const o2 = new Person()

// 这样写的话,我们两个对象内的 `sayHi` 函数代码一摸一样且功能一摸一样但是占用了两个内存空间,也就是说 o1.sayHi 是一个地址,o2.sayHi 是一个地址(o1.sayHi !== o2.sayHi)
// 解决办法:原型