一次性搞定 JS “引用类型” 的运算特点

194 阅读2分钟

标准内置对象 Object 运算特点 学习笔记

参考资料:MDN Object

概念 

Object 是 JavaScript 的一种 数据类型 。它用于存储各种键值集合和更复杂的实体。Objects 可以通过 Object() 构造函数或者使用 对象字面量 的方式创建

对象的“引用”

1.property 运算符(. 或 [ ]) 根据是否存在 触发 get 或 set

js 没有成员运算符这个概念,但它的特性是客观存在的,也是与成员运算符相似的。 成员在 Object 中 是 property,例如下面的这个例子中,name 就是 rightObj 的成员,所以暂时叫他 property 运算符好了。

    // 字面量方式创建一个名为 rightObj 的对象。
    const rightObj = { name:'程序员' }
  
    // 使用.或者[]对属性进行运算的时候
    rightObj.name  // 存在的属性 触发 get
    rightObj['name']  // 存在的属性 触发 get
    
    rightObj.title // 不存在的属性 触发 set
    rightObj['title'] // 不存在的属性 触发 set
    
    delete rightObje.age // 删除不存在的属性 静默失败

2. 对象作为右值时,左值和右值 的 property 运算 相互“引用”。

    // 字面量方式创建一个名为 rightObj 的对象。
    const rightObj = { name:'程序员', child: { name: 'baby' } }
    
    // rightObj 赋值 到 left 
    let left = rightObj
    
    // 左值的属性操作(get,set)会影响 right 对象
    left.name = '工程师'
    console.log(rightObj.name) // '工程师'
    
    // 右值的属性操作(get,set)也会影响 left
    rightObj.name = '架构师'
    console.log(left.name) // 架构师
    
    // delete 运算 会相互影响
    delete rightObj.child.name 
    console.log(rightObj) // {name:'程序员',child:{}}
    Object.is(rightObj,left) // true
    
    // 冻结属性拓展 
    Object.preventExtentions(rightObj) //{name: '程序员', child: {…}}
    rightObj.age = 18 // 18 
    console.log(rightObje.age) //undefined 静默失败。。。
    
    left.age = 18 //18
    console.log(left.age) //undefined 静默失败。。。
    

3. 赋值运算建立新的引用关系

    // 左值 和 右值的非 属性操作对彼此 没有任何影响
    let initObj = { val: 1, next: { val: 2 } }
    
    // 赋值运算
    let listNode = initObj
    
    // 左值 进行了赋值操作,指向了新的地址(listNode.next),与 initObj 没有关系了。
    listNode = listNode.next; // { val: 2 }
 
    // 右值的赋值操作对左值无影响,这里的右值指得是(listNode.next) 而不是 listNode
    listNode.next = { val: 3 } 
    console.log(listNode) // { val: 2} 没有变化
    
    // 右值(listNode.next)的 property 操作 会影响左值
    listNode.next.next = null // 这里相当于是  (listNode.next).next, 右值是 (listNode.next)
    console.log(listNode) // { val: 2, next: null}
    

总结

引用类型引用的其实是对属性成员的取值,赋值,以及运算操作