美文网首页
对象的定义

对象的定义

作者: 东方三篇 | 来源:发表于2021-11-23 18:12 被阅读0次

    对象定义

    ECMA-262将对象定义为一组属性的无序集合。意味着对象就是一组没有特定顺序的值。 对象的每个属性或方法都由一个名称来标识,这个标识映射到一个值。我们可以想象对象就是一组散列的表,内容就是键值对,值可以是数据或者函数。
    

    1. 实例化对象

    const person = new Object()
    person.name = 'tom'
    person.sayName = function () {
        console.log(this.name)
    }
    # OR
    // 对象字面量方式更为常见
    const person = {
        name: 'tom',
        sayName () {
            console.log(this.name)
        }
    }
    

    2. 属性的类型

    ECMA-262使用一些内部特性来描述属性的特征,这些特征是有javascript实现引擎的规范定义的,因此,开发者不能在javascript中直接访问这些特性。为了将某个特性标识成内部特性, 规范用两个中括号把特性的名称包括起来。属性分为数据属性和访问器属性。
    
    1. 数据属性

      a. 数据属性包含一个保存数据值的位置。 值会从这个位置读取, 也会写入到这个位置。有四个特性描述它们的行为:

    • [[Configurable]]: 属性是否可通过 delete 来删除或者重新定义,是否可以修改他的特性。以及是否可以改为访问器属性,默认为 true

    • [[Enumberable]]: 是否可以通过 for-in 来遍历,默认true

    • [[Writable]]: 是否可以被修改,默认 true

    • [[Value]]: 包含属性的实际值。 就是那个读取和写入属性值的位置, 默认 undefined

      b. 要修改默认属性,就必须使用 Object.defineProperty()方法。 接收三个参数: 要给其添加属性的对象, 属性的名称, 一个描述符对象(即描述符对象上的属性可以包括: configable, enumable, writable, vlaue; 跟相关特性的名称一一对应)。

    const person = new Object()
    Object.defineProperty(person, 'name', {
        writable: false,
        value: 'tom'
    })
    // 声明一个person对象,并且添加一个不能修改的 name 属性, 属性值是 tom
    // 在调用 Object.defineProperty() 方法时, 如果不指定 configable, writable, enumable的值, 则默认为 false.
    
    1. 访问器属性

      a. 访问器属性不包含数据值。 而是包含一个获取(getter)函数和一个设置(setter)函数。不过这两个函数并不是必须的。在读取访问器属性时, 会调用 getter 函数, getter 函数负责返回一个有效的值。 在写入访问器属性时, 会调用 setter 函数并传入新值, setter 函数决定对数据做什么样的修改。访问器属性有4个特性描述它们的行为:

      • [[Configurable]]: 属性是否可通过 delete 来删除或者重新定义,是否可以修改他的特性。以及是否可以改为访问器属性,默认为 true
      • [[Enumberable]]: 是否可以通过 for-in 来遍历,默认true
      • [[Get]]: getter函数, 在读取属性时调用, 默认 undefined
      • [[Set]]: setter函数, 在写入属性时调用, 默认undefined

      b. 访问器属性不能直接定义的,必须使用 Object.defineProperty()方法来实现, getter和setter不一定都要定义。指定要 getter 则默认为属性是只读。

      const book = {
          year_: 2017,
          edition: 1
      }
      Object.deinfineProperty(book, 'year', {
          get () {
              return this.year_ // year_ 这样的下划线通常用来表示该属性不希望在对象的外部被访问
          },
          set (newValue) {
           if (newValue > 2017) {
                  this.year_ = newValue
               this.eidtion += newValue - 2017
              }
       }
      })
      book.year = 2018
      console.log(book.edition) // 2
      
      // book 定义了两个默认属性 year_, edition.
      // 另一个属性year定义为访问器属性,getter函数返回 year_ 的值, setter函数则是通过一些计算确定 edition的值。
      // 把year属性修改成2018,或导致year_也是2018,edition成为2.
      

    3. 定义多个属性

    const book = new Object()
    Object.defineProperties(book, {
        year_: { value: 2017 },
        edition: { value: 1 },
        year: {
            get () {
                return this.year_
            },
            set (newValue) {
                if (newValue > 2017) {
                    this.year_ = newValue
                    this.eidtion += newValue - 2017
                }
            }
        }
    })
    // 上述代码一次性为book对象定义两个数据属性year_和edition, 还定义了一个访问器属性 year
    

    4. 读取属性的特性

    a. 使用 Object.getOwnPropertyDescriptor()方法可以取得指定属性的属性描述符。
    
    // 用 3.定义多个属性的代码示例
    const descriptor = Object.getOwnPropertyDescriptor(book, 'year_') // 数据属性
    descriptor.value // 2017
    descriptor.configable // false
    typeof descriptor.get // undefined
    const desYear = Object.getOwnPropertyDescriptor(book, 'year') // 访问器属性
    desYear.value // undefined
    desYear.enumable // false
    type desYear.get // function
    
    b. ECMA-2017提供了一个 Object.getOwnPropertyDescriptors()静态方法。
    
    // 使用 3.定义多个属性的代码示例
    console.log(Object.getOwnPropertyDescriptors(book))
    {
        edition: { // 数据属性
            configable: false,
            enumable: fasle,
            value: 1,
            writable: false
        },
        year_: { // 数据属性
            configable: false,
            enumable: fasle,
            value: 2017,
            writable: false
        },
        year: { // 访问器属性
            configable: false,
            enumable: fasle,
            get: f(),
            set: f(newVlaue)
        }
    }
    

    5. 合并对象

    javascript开发者经常觉得 “合并(merge)” 两个对象很有用。就是把源对象所有的本地属性一起复制到目标对象上。 有时候这种操作也被称为 “混入(mixin)” 目标对象通过混入源对象的属性得到了增强。ES6提供了 专门用来合并对象的方法Object.assgin(). 接收一个目标对象和一个或者多个源对象作为参数, 然后将源对象中每个可枚举(Objct.propertyIsEnumerable()返回true)和自有(Object.hasOwnProperty()返回true)的属性复制到目标对象。以字符串和符号为键的属性会被复制。对每个符合条件的属性,都会使用源对象上的getter取得属性的值, 然后使用目标对象上的setter设置属性的值。
    
    const target = { id: 'target', value: 123 }
    const source1 = { id: 'source1', a: 'foo' }
    const source2 = { id: 'source2', a: 'bar', c: {}}
    const result = Object.assgin(target, source1, source2)
    console.log(result) // {id: 'source2', value: 123, a: 'bar', c: {}} 重复的属性会被后面定义的所覆盖
    console.log(result.c === source2.c) // true, 表示是浅复制(只会复制对象的引用)
    

    6. 对象标识以及相等判断

    true === 1 // false
    Object.is(true, 1) // false
    {} === {} // false
    Object.is({}, {}) // false
    '2' === 2 // false
    Object.is('2', 2) // false
    +0 === -0 // true
    Object.is(+0, -0) // false
    0 === +0 // true
    Object.is(0, +0) // true
    0 === -0 // true
    Object.is(0, -0) // false
    
    NaN === NaN // false
    isNaN(NaN) // true
    Object.is(NaN, NaN) // true
    

    7. 增强对象语法(同样适用ES6的类)

    1. 属性值简写
    let name = 'tom'
    const person = {
     name
    }
    console.log(person) // {name: 'tom'}
    
    1. 可计算属性
    // 使用可计算属性之前
    const nameKey = 'name'
    cosnt ageKey = 'age'
    const jobKey = 'job'
    let person = new Object()
    person[nameKey] = 'tom'
    person[ageKey] = 18
    persion[jobKey] = 'student'
    // 使用计算属性
    let person = {
     [nameKey]: 'tom',
     [ageKey]: 18,
     [jobKey]: 'student'
    }
    
    
    1. 简写方法名

      const obj = {
       sayName: function (n) {console.log('say hello' + n)} // 没有简写
       sayNmae (n) { console.log('say hello' + n) } // 简写
      }
      

    8. 对象的解构

    对象解构就就是使用与对象匹配的结构来实现对象属性赋值。
    
    const person = {
        name: 'tom',
        age: 19,
        desc: {
            title: 'hello student'
        }
    }
    const {name, age: personAge, desc, job = 'student', score} = person
    console.log(name, personAge, job, score) // tom, 19, {title: 'hello student'}, student, undefined
    const { desc:{title} } = person // 嵌套解构
    console.log(title) // 'hello student'
    

    相关文章

      网友评论

          本文标题:对象的定义

          本文链接:https://www.haomeiwen.com/subject/ssowtrtx.html