美文网首页前端学习指南饥人谷技术博客让前端飞
《高程第六章---面向对象程序设计》小结---理解对象

《高程第六章---面向对象程序设计》小结---理解对象

作者: 大春春 | 来源:发表于2017-11-26 11:09 被阅读22次

《JavaScript高级程序设计》这本书比较厚,之前刚学JS的时候挑战过一次,结果止步第三章。现在工作了一段时间想想还是得回过头来补充一下基础知识的。目前刚看完第六章,就从第六章开始总结吧,再逐步补充之前的好了。

理解对象

该章节讲解了JS中对象的属性类型以及对象属性间的一些设置。

JS中的对象是什么

  • JS中的对象只是一堆属性和值的无序集合,值的类型包括基本类型,函数,或者对象。
  • 属性和值之间的关系是映射关系,遵循key: value的规范。

如何创建对象

JS中创建对象的方法非常简单,有两种:

  • 使用Object构造函数
let a = new Object()
a.name = 'oxc'
console.log(a) // {name: "oxc"}

当然,你也可以在Object构造函数中传入一个参数,然后创建出来的对象是原始数据类型对象。

let a = new Object(1) // Number {[[PrimitiveValue]]: 1}
console.log(a) // 1
typeof a // 'object'
  • 使用对象字面量创建对象
let a = {
    name: 'oxc'
}
console.log(a) // {name: "oxc"}

对象的属性类型

该章节介绍了JS对象属性的类型及其特点,其中属性类型分为了数据属性访问器属性两种,同时介绍了定义属性特征值的api: defineProperty()defineProperties,以及读取对象属性特征值的api: getOwnerPropertyDescriptor()

  • 对象属性的特征值
    • 介绍:
      对象属性的特征值是对象的属性的一些特性,可以在定义该属性的时候进行设置,但是在JS中是不能直接对其进行访问的。
    • 分类
      • configurable: 表示该属性是否能够被关键词delete删除并进行重新定义,以及该属性的特性和属性类型能否被修改;
      • enumerable: 设置该属性能否被for-in循环遍历到;
      • writable: 设置该属性的值能否被修改;
      • value: 设置该属性的值;
      • get: 访问该属性的时候执行的函数;
      • set: 对该属性的值进行设置的时候执行的函数;
  • 关于Object.definePropertyObject.defineProperties
    这两个api的作用就是用来设置上面的对象属性特征值的
    • Object.defineProperty
      该api用于设置单个对象属性的特征值,接受三个参数,顺序是需要设置属性特征值的对象,需要设置的属性,然后是特征值,使用示例如下
        let a = {}
        Object.defineProperty(a, 'name', {
            configurable: true,
            enumerable: true,
            writable: true,
            value: 'oxc'
        })
        console.log(a)  //  {name: 'oxc'}
  • Object.defineProperties
    该api和defineProperty作用一致,但是可以批量设置对象属性特征值,示例如下:
        let a = {}
        Object.defineProperties(a, {
            name: {
                value: 'oxc',
                writable: false
            },
            age: {
                value: 12,
                writable: false
            }
        })
        console.log(a)  // {name: "oxc", age: 12}
  • 对象的属性类型(数据属性和访问器属性)
    • 数据属性
      • 介绍: 对象的数据属性只标明数据值的位置,在该位置可以对值进行访问和写入。
      • 数据属性包含的特征值有:configurable, enumerable, writable, value
      • 如何定义一个数据属性:
        let a = {}
        Object.defineProperty(a, 'name', {
            configurable: false,
            enumerable: false,
            writable: false,
            value: 'oxc'
        })
        console.log(a)  //  {name: 'oxc'}
        // 该例子创建了一个名为name的属性,该属性可以被delete删除,for-in循环无法遍历它,也无法对其值进行修改,他的值为`oxc`,并且也不可以在下面对其属性特征值进行重写,重写特征值不会有任何反应。
       // 该属性就是数据属性,值得一提的是,用对象字面量或者对象构造函数新建的对象属性`configurable`,`writable`,`enumerable`三个值默认都为true
  • 访问器属性
    • 介绍: 访问器属性是指通过这个属性去对象的属性;
    • 访问器属性包含的特征值有:configrable,enumerable,get,set;
    • 定义一个访问器属性
        let a = {
            _name: 'oxc'
        }
        Object.defineProperty(a, 'name', {
            configurable: false,
            enumerable: true,
            get() {
                return this._name
            },
            set(value) {
                this._name = value
            }
        })
    //  这时候我们可以通过调用a.name来对_name属性进行访问和写入,并且可以在访问和写入的过程中通过get和set做一些手脚,例如我想通过name读取到的是123,可以在get函数中这么写
    get(){ return 123 }
    console.log(a.name)   // 123
// 又或者我想别人无论怎么设置a.name, a._name都是123,就可以在set函数中这么写
    set(value){ this._name = 123 }
// 另外值得一提的是,如果enumerable设置为true, 那么访问器属性name也是可以可以被for-in循环遍历到的
  • 访问器属性的用途
    访问器属性除了上面所说的功能,在实际中的用途也是很广的,其中用得最多的一条就是用getset函数通过计算对目标对象的其它属性进行修改,如下例子:
        let a = {
            _name: 'oxc',
            age: 10
        }
        Object.defineProperty(a, 'name', {
            configurable: false,
            enumerable: true,
            get() {
                return this._name
            },
            set(value) {
                value === '大春春' ? this.age = 80 : this.age = 10
            }
        })
        a.name = '大春春'
        console.log(a)      //  {_name: "oxc", age: 80}
  • 值得一提的是,当前Vue的响应式系统的原理就是利用Object.defineProperty进行设置的,关于这点可以查看我的这篇博客关于Vue的MVVM

  • 关于属性特征默认值

    • 如果使用普通的对象创建方法创建的对象,就是不使用Object.definePropertyObject.defineProperties创建的属性,那么默认是数据属性,并且configurable,enumerable,'writable'都是true
    • 但是如果使用的是Object.definePropertyObject.defineProperties创建的数据属性,那么configurable,enumerable,'writable'都是false访问器属性一样默认configurableenumerable都为false
// 普通创建的对象属性特征值
        let a = {
            name: 'oxc'
        }
        let b = Object.getOwnPropertyDescriptor(a, 'name')
        console.log(b) // {value: "oxc", writable: true, enumerable: true, configurable: true}
// 使用Object.defineProperty创建的属性
        let a = {}
        Object.defineProperty(a, 'name', {
            value: 'oxc'
        })
        let b = Object.getOwnPropertyDescriptor(a, 'name')
        console.log(b) // {value: "oxc", writable: false, enumerable: false, configurable: false}

读取属性的特性

读取属性的特征值可以用Object.getOwnPropertyDescriptor, 该方法接受两个参数,第一个参数是需要读取的属性所在的对象,第二个是需要读取的属性,例子如上默认值例子。

相关文章

网友评论

    本文标题:《高程第六章---面向对象程序设计》小结---理解对象

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