JS面向对象(一)

218 阅读4分钟

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

面向对象

对象是JavaScript中一个非常重要的概念

因为对象可以把多个相关的数据封装到一起,更全面的描述一个事物

c93fb539eea5fd9e1e88b626867a2194(1).png 比如我们可以描述一个人: 男孩,名字我妻善逸,年纪16,身高164.5,正在哭泣

通过代码的形式来描述:

 var boy = {
      name: "我妻善逸",
      age: 16,
      height: 1.645,
      action: function() {
        console.log(this.name + "正在哭泣~")
      }
 }

用对象来描述事物,更有利于我们将现实的事物,抽离成代码中某个数据结构

JavaScript中创建对象的两种方式

  1. 通过new Object()的方式创建一个空的对象
var boy = new Object()
    boy.name = '我妻善逸'
    boy.age = 16
    boy.height = 1.645
    boy.action: function() {
        console.log(this.name + "正在哭泣~")
      }
  1. 同过字面量的形式创建对象
 var boy = {
      name: "我妻善逸",
      age: 16,
      height: 1.645,
      action: function() {
        console.log(this.name + "正在哭泣~")
      }
 }

对象属性的操作

  1. 获取对象的属性
 console.log(boy.name)
 // 我妻善逸
  1. 给属性赋值
 boy.name = "灶门祢豆子"
 console.log(boy.name)
 // 灶门祢豆子
  1. 删除属性
 delete obj.name
 console.log(boy)
 // { age: 16, height: 1.645, action: [Function: action] }

如果我们想对对象中的某些属性进行一些限制:比如说是不可以重新给某个属性重新赋值?、不可以通过delete的方式删除某个属性?

如果我们想对属性进行比较精准的操作控制,我们就可以使用属性描述符。

属性描述符

属性描述符需要使用 Object.defineProperty 来对属性进行添加或者修改;

Object.defineProperty() 方法会直接在一个对象上面定义一个或多个新的属性,或者是修改对象的现有属性,并且返回此对象

 Object.defineProperty(obj,prop,descriptor)

传入的三个参数:

  1. obj 要定义属性的对象;
  2. prop 要定义或者是修改的属性的名称
  3. descriptor 要定义或者是修改的属性的描述符

属性描述符的两个分类

数据属性描述符(Data Properties Descriptor)

访问器属性描述符(Accessor Properties Descriptor)

数据属性描述符

数据属性描述符有四个特性:

  • Value : 当前属性的value值,默认值为undefined
Object.defineProperty(boy,"wife",{
  value:"灶门祢豆子"
 })
console.log(boy.wife)
// 灶门祢豆子
  • Writable: 是否可以修改当前属性的值

    当直接在一个对象上定义某个属性时,该属性的 Writable 为 true ;

    当通过属性描述符定义某个属性时,该属性的 Writable 为 false ;

Object.defineProperty(boy,"wife",{
  value:"灶门祢豆子",

})
console.log(boy.wife)// 灶门祢豆子

boy.wife = "蝴蝶忍"
console.log(boy.wife)// 灶门祢豆子 

Writable的默认值是false 所以无法修改boy中wife的值

Object.defineProperty(boy,"wife",{
  value:"灶门祢豆子",
  writable: true

})
console.log(boy.wife)// 灶门祢豆子

boy.wife = "蝴蝶忍"
console.log(boy.wife)// 蝴蝶忍 
  • Configurable: 当前属性描述符是否可被改变、是否可被删除

    当直接在一个对象上定义某个属性时,该属性的 Configurable 为 true ;

    当通过属性描述符定义某个属性时,该属性的 Configurable 为 false ;

Object.defineProperty(boy,"wife",{
  value:"灶门祢豆子",
})
delete boy.wife
delete boy.name
console.log(boy.wife,boy.name)// 灶门祢豆子 undefined

Configurable的默认值是false 所以无法删除boy中wife的值

Object.defineProperty(boy,"wife",{
  value:"灶门祢豆子",
  configurable: true,
})
delete boy.wife
delete boy.name
console.log(boy.wife,boy.name)//  undefined undefined
  • Enumerable: 当前属性是否可被枚举

    当直接在一个对象上定义某个属性时,该属性的 Enumerable 为 true ;

    当通过属性描述符定义某个属性时,该属性的 Enumerable 为 false ;

Object.defineProperty(boy,"wife",{
  value:"灶门祢豆子",
})
console.log(boy)//{ name: '我妻善逸', age: 16, height: 1.645, action: [Function: action] }

Enumerable的默认值是false,无法找到当前属性

Object.defineProperty(boy,"wife",{
  value:"灶门祢豆子",
  enumerable: true,
})
console.log(boy)//{name: '我妻善逸',age: 16,height: 1.645,action: [Function: action],wife: '灶门祢豆子'}

访问器属性描述符

访问器属性描述符有四个特性:

  • Value : 当前属性的value值,默认值为undefined

  • Writable: 是否可以修改当前属性的值

    当直接在一个对象上定义某个属性时,该属性的 Writable 为 true ;

    当通过属性描述符定义某个属性时,该属性的 Writable 为 false ;

  • Get: 获取当前属性时会执行的函数,默认值为undefined

  • Set: 设置当前属性时会执行的函数,默认值为undefined Vue2中响应式原理用的就是通过Object.defineProperty访问器属性描述符实现的,get时收集依赖,set时通知依赖,达到响应式更新的目的

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(boy.wife)

boy.wife = "蝴蝶忍"
console.log(boy.wife)

function foo() {
  console.log("获取了wife的值")
}

function bar() {
  console.log("设置了wife的值")
}

// 输出的结果
// 获取了wife的值
// 灶门祢豆子
// 设置了wife的值
// 获取了wife的值
// 蝴蝶忍