重学javaScript (十八)|面向对象中的对象创建

82 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第19天,点击查看活动详情

前言

上一节,我们学习了对象的两种创建方式和object的defineProperty方法,其中对象也有许多其他的常用方法,再者不管是字面量的方式还是new关键字的方式,就只能创建一个对象。我们接下来分别来看看这两个问题

对象中的其他方法

  • Object.preventExtensions():禁止对象扩展新属性。

  • Object.seal():将对象密封起来,不允许配置和删除属性。(它的内部是调用preventExtensions,然后将将现有属性的configurable设置为false

  • Object.freeze():将对象冻结起来,不允许修改对象现有属性。(本质上是调用seal,并且将现有属性的writable设置为false

  • Object.getOwnPropertyDescriptor: 获取单个的属性的描述符

  • Object.getOwnPropertyDescriptors: 获取多个的属性的描述符

let obj = {
    name: 'juejin',
    age: 22
}
let a = Object.getOwnPropertyDescriptor(obj, 'name')
let b = Object.getOwnPropertyDescriptors(obj, 'name')

console.log(a)
console.log(b)

image.png

创建对象的方式

上节写到了对象字面量和new关键字的创建,这样都是创建单个的对象,在说创建多个之前,我们先来复习下,new关键字创建对象,内存里都做了哪些操作

new 关键字创建对象时的内存变化

  • 创建一个全新的对象
  • 这个新对象会被执行prototype连接
  • 这个新对象会被绑定到函数调用的this上(this绑定在这个时候完成)
  • 执行函数的内部代码(函数体代码)
  • 如果函数没有返回其他对象,函数会返回这个新对象

这就是new关键字来创建对象的过程

工厂函数

当我们创建一个对象后,如果需要创建多个对象,则需要一直重复的写,工厂函数可以解决这一痛点

function createObj(name, number) {
    // 创建一个空对象
    const obj = {}
  
    obj.name = name
    obj.number = number
    obj.goal = function() {
      console.log(`${this.number}${this.name}, 进球了!!!!!!!!!!!!!!`)
    }
  
    // 将对象返回
    return obj
  }

这时我们只需将参数传入就可以创建一个对象,我们来试一下

  let kaka = createObj('kaka','22')
  let ronaldo = createObj('ronaldo','7')
  console.log(kaka)
  console.log(ronaldo)
  kaka.goal()
  ronaldo.goal()

image.png

工厂函数的缺点

这样的确可以创建多个对象,但是这些对象都没有自己的类型,它都是object类型的


  let kaka = createObj('kaka','22')
  let ronaldo = createObj('ronaldo','7')

别着急,我们可以用构造函数来解决这个问题

构造函数

上边我们说了new关键字做了哪些操作,可以回头看下 我们现在来说构造函数怎么创建对象

function Player(name, number) {
    this.name = name
    this.number = number

    this.goal = function () {
        console.log(`${this.number}${this.name}, 进球了!!!!!!!!!!!!!!`)
    }
}

let kaka = new Player('kaka', 22)
let ronaldo = new Player('ronaldo', 7)
kaka.goal()
ronaldo.goal()
console.log(kaka)
console.log(ronaldo)

image.png

从代码的运行结果可以看出来,kaka和ronalod的类型是Player了

构造函数的缺点

我们创建对象后的公用方法,每次创建一个,它都会创建一个对象,比较占用内存

let kaka = new Player('kaka', 22)
let ronaldo = new Player('ronaldo', 7)

console.log(kaka.goal === ronaldo.goal)

image.png