JS面向对象(二)

93 阅读3分钟

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

关于对象方法的补充

  • 获取对象某个属性的描述符 Object.getOwnPropertyDescriptor
 var boy = {
      name: "我妻善逸",
      age: 16,
      height: 1.645,
      _wife:"灶门祢豆子",
      action: function() {
        console.log(this.name + "正在哭泣~")
      }
 }
 
Object.defineProperty(boy,"wife",{
  enumerable: true,
  configurable: true,
  get: function() {
    foo()
    return this._wife
  },
  set: function(value) {
    bar()
    this._wife = value
  }
})

console.log(Object.getOwnPropertyDescriptor(boy, "wife"))
// 打印结果
// {
//   get: [Function: get],
//   set: [Function: set],
//   enumerable: true,
//   configurable: true
// }

  • 获取对象全部属性的描述符 Object.getOwnPropertyDescriptors
console.log(Object.getOwnPropertyDescriptors(boy))
// 打印结果
// {
//   name: {
//     value: '我妻善逸',
//     writable: true,   
//     enumerable: true,
//     configurable: true
//   },
//   age: { value: 16, writable: true, enumerable: true, configurable: true },
//   height: {
//     value: 1.645,
//     writable: true,
//     enumerable: true,
//     configurable: true
//   },
//   _wife: {
//     value: '灶门祢豆子',
//     writable: true,
//     enumerable: true,
//     configurable: true
//   },
//   action: {
//     value: [Function: action],
//     writable: true,
//     enumerable: true,
//     configurable: true
//   },
//   wife: {
//     get: [Function: get],
//     set: [Function: set],
//     enumerable: true,
//     configurable: true
//   }
// }

  • 禁止对象添加新的属性 Object.preventExtensions(给一个对象添加新的属性会失败)
var boy = {
  name: "我妻善逸",
  age: 16,
  height: 1.645,
  wife:"灶门祢豆子",
  action: function() {
    console.log(this.name + "正在哭泣~")
  }
}


Object.preventExtensions(boy)

boy.birthday = 0221

console.log(boy)
// 打印结果
{
  name: '我妻善逸',
  age: 16,
  height: 1.645,
  wife: '灶门祢豆子',       
  action: [Function: action]
}

  • 密封对象,不允许配置和删除属性 Object.seal(对象调用delete方法删除属性会失效)
Object.seal(boy)
delete boy.name
console.log(boy.name)// 我妻善逸

创建多个对象的方法

如果我们现在希望创建一些对象:例如善逸的朋友们,那么应该采取什么方式创建比较好呢?

e3b320cf85330225c159b746dbc5409c.jpeg

06d34e359477f59e4de317299e6e31ae.jpeg

上篇我们已经学习了创建对象的两种方式 new Object方式 和 字面量创建的方式

首先我们使用字面量创建的方式

var boy1 = {
  name: '我妻善逸',
  age: 16,
  height: 1.645,
  weight: 58
}

var boy2 = {
  name: "灶门炭治郎",
  age: 15,
  height: 1.65,
  weight: 61
}

var boy3 = {
  name: "嘴平伊之助",
  age: 15,
  height: 1.64,
  weight: 63
  
}

但是这方式有很多弊端:创建同样的对象时,需要写很多重复的代码

我们可以想到一种其他方法创建对象:工厂模式 需要将重复代码进行抽取的工作

function createBoy(name, age, height, weight) {
  var boy = {}
  boy.name = name
  boy.age = age
  boy.height = height;
  boy.address = weight
  return boy
}

var boy1 = createBoy("我妻善逸", 16, 1.645, 58)
var boy2 = createBoy("灶门炭治郎", 15, 1.65, 61)
var boy3 = createBoy("嘴平伊之助", 15, 1.64, 63)

console.log(boy1, boy2, boy3)
// { name: '我妻善逸', age: 16, height: 1.645, address: 58 } { name: '灶门炭治郎', age: 15, height: 1.65, address: 61 } { name: '嘴平伊之助', age: 15, height: 1.64, address: 63 }

构造函数

在工厂模式创建对象时有些问题,我们在打印对象时,对象的类型都Objcet类型,但是从其他角度去看,这些对象应该有一个共同的类型; 下面我们使用另外一种方式去创建对象:构造函数的方式

我们要理解一下在JavaScript中的构造函数是什么?

首先要明确一点构造函数(constructor)和普通的函数是没有任何区别的,当一个普通函数被使用new操作符来调用,那么我们就可以把这个函数叫做构造函数。

new操作符

当一个函数被new操作符调用会执行哪些操作呢?

  1. 会在内存中创建一个新的对象(空对象);
  2. 这个新对象会被执行[[prototype]]连接;
  3. 构造函数内部的this,会指向创建出来的新对象;
  4. 执行函数内部代码(函数体本身);
  5. 如果构造函数本身没有返回非空对象,则返回创建出来的新对象;
function foo() {
  console.log("函数体")
}
var f1 = new foo
console.log(f1)
// 打印结果
//  函数体
// foo {}

使用构造函数创建对象

function Boy(name, age, height, weight) {
  this.name = name
  this.age = age
  this.height = height
  this.weight = weight
}


var boy1 = new Boy("我妻善逸", 16, 1.645, 58)
var boy2 = new Boy("灶门炭治郎", 15, 1.65, 61)
var boy3 = new Boy("嘴平伊之助", 15, 1.64, 63)

console.log(boy1) //Boy { name: '我妻善逸', age: 16, height: 1.645, weight: 58 }
console.log(boy2) //Boy { name: '灶门炭治郎', age: 15, height: 1.65, weight: 61 }
console.log(boy3) //Boy { name: '嘴平伊之助', age: 15, height: 1.64, weight: 63 }