《JavaScript 语言精粹》对象篇

113 阅读4分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

《JavaScript 语言精粹》 第三章对象读完后的一些笔记摘录

本章节主要介绍了如何创建一个字面量的对象,对象属性值是如何获取和修改的,如何删除对象属性,创建对象的原型继承以及对象属性的枚举。

字面量

  • 一对花括号包裹的键值对结构
  • 属性名可以是包括空字符的任何字符串
  • 属性名需要加引号,但是如果是合法的并且不是关键字的,可以不加引号
  • 属性值可以是任何的 JS 数据类型
  • 用逗号分隔"键/值"
  • 属性值可以包含另一个对象字面量在内的任意表达式
    var obj = {
        name: "abc",
        "first-name": "ccc",  // first-name 不是合法的标识符所以要加引号
        item: {
            name: "ddd",
            age: 18
        }
    }

检索

对象的检索方法有两种,一种是用 [] 包围字符串表达式,另一个种就是用 . 表示。

  1. [] 来获取
    var obj = {
        name: "abc",
        "first-name": "ccc",
    }
    
    obj['name']
    obj['first-name']
  1. . 表示要注意字符串表达式是一个字面量的字符串,而且是一个 JS 合法的标识符并且不是关键字
    var obj = {
        name: "abc",
        "first-name": "ccc"
    }
    
    obj.name // 合法
    obj.first-name // 不合法

如果检索的是一个不存在的属性成员的话,会返回undefinde,可以使用 || 运算符来填充默认值

    var obj = {
        name: "abc",
        "first-name": "ccc"
    }
    
    var type = obj.type || 'none'

当尝试在 undefined 的成员属性上获取值的话会 导致 TypeError异常,可用通过 && 运算符来避免

    var type = obj.item && obj.item.type

更新

对象里的值可以通过赋值方式来更新,如果属性名存在对象里面,那么这个属性值就会被替换。如果属性名不在对象里面,那么就会在这个对象上新建一个属性名

    var obj = {
        name: "abc",
    }
    
    obj.name = 'ccc' // name 的值被更新为 ccc
    obj.age = 18 //  obj {name: 'ccc', age: 18}
    

引用

因为对象是一个复杂的数据类型,JS 会把创建的对象存放堆里面,而栈中只存放对象的在堆中的地址。创建一个变量并且值是一个对象,再把这个变量赋值给另一个变量,那么这两个变量都指向同一个对象,赋值的过程只是把对象的引用地址赋值给了另一个变量

    var obj = {
        name: "abc",
    }
    
    var x = obj
    x.name = 'ccc'
    // {name: 'ccc'}  最终name属性值都是 ccc

原型

  • 每个对象都连接着原型,并且可以继承原型中的属性。字面量创建的对象都连接着Object.prototype。
  • 当创建一个对象的时候,可以选择某个对象作为它的原型对象。可以使用Object.create() 方法(这个方法就是原型式继承方法,现在语法是支持的,下面是一个实现原理)。
    if(typeof Object.create !== 'function'){
        Object.create = function(o){
            var F = function(){}
            F.prototype = o
            return new F()
        }
    }
  • 原型连接在对象做出修改时,是不会涉及到原型的。在原型上添加一个属性,那么所有的实例对象都会获取到这个属性值。
    var obj = {name: 'abc'}
    var objInstance = Object.create(obj)
    objInstance.name = 'ccc'
    
    console.log(obj) // {name: 'abc'}
    console.log(objInstance) // {name: 'ccc'}
  • 原型连接只有在检索值的时候才被用到。当获取对象的某一个属性的时候,会先从自身上查找属性,若没有则会从原型对象上查找,若还是没有则会在这个原型对象的原型对象上面查找,以此类推直到Object.prototype 上,若有则返回,没有就返回 undefined,这一条链式叫做原型链。

反射

  • 检查对象并确定对象具有什么属性,只要检索该属性并且验证该值就可以了,通常使用typeof
    var obj = { name: '111', age: 18 }
    typeof obj.name // string
    typeof obj.age // number
  • 原型链中的任何属性都会产生值
    typeof obj.toString // function
    typeof obj.constructor // function
  • 可以使用 hasOwnProperty 来判断属性是否存在于对象自身
    obj.hasOwnProperty(name) // true
    obj.hasOwnProperty(constructor) // false

枚举

  • for in 可以变量对象上所有的可枚举属性,包括原型链上的。
  • 可以用 hasOwnProperty 来过滤非自身属性,用 typeof来去除不想要要的

删除

  • 删除对象属性需要使用 delete 运算符。
  • 对象中存在该属性,则该属性会被移除
  • 这个操作不会涉及原型链中的任何对象
  • 删除自身与原型链同名属性,则会将原型链上的属性透现出来

减少全局变量污染

  • 在全局中创建一个唯一的全局变量,将程序全局性的资源都容纳到一个名称之下,就能大大降低和其他第三方程序、组件库之间的冲突