ES6学习笔记--对象的拓展

151 阅读3分钟

属性的拓展

属性的简介表示法

ES6允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

let a = 1
let age={
    a
}
console.log(age) //{a:1}
除了属性可以简写之外,方法也可以简写

let f = {
    foo(){}
}
//相当于
let f = {
    foo:function () {}
}
在函数返回值的时候,可以这样写

function add(x, y) {
    let x = x + 1
    let y = y + 1
    return {
        x,
        y 
   }
}
CommonJS模板输出一组变量,可以这样写

function getItem(key) {
    return obj[key]
}

function setItem(key, value) {
    obj[key] = value
}

module.exports = {
    getItem,
    setItem
}

属性的可枚举性与遍历

对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。

let foo = {
	age:20
}
Object.getOwnPropertyDescriptor(foo,'age')
//{
     configurable: true,
     enumerable: true,
     value: 20
     writable: true
   }
如果enumerable属性为false,则不可以用以下方法来进行遍历
  • for...in循环:只遍历对象自身的和继承的可枚举的属性。
  • Object.keys():返回对象自身的所有可枚举的属性的键名。
  • JSON.stringify():只串行化对象自身的可枚举的属性。
  • Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。

遍历对象的方法

let symbol = Symbol()
let foo = {
    age: 20,
    name: 'David',
    [symbol]: 'symbol'
}
  • for...in
for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。

for (let i in foo) {
    console.log(i) // age name
}
  • Object.keys(obj)
Object.keys()返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。

Object.keys(foo).forEach(item => {
    console.log(item)  //age name
})
  • Object.values(obj)
Objec.values()返回一个数组,包括对象自身(不含继承的)的所有可枚举属性的键值(不含Symbol属性)

Object.values(foo).forEach(item => {
    console.log(item) //20 David
})
  • Object.getOwnPropertyNames(obj)
Object.getOwnPropertyNames()返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。

Object.getOwnPropertyNames(foo) //['age','name']
  • Object.getOwnPropertySymbols(obj)
Object.getOwnPropertySymbols()返回一个数组,包含对象自身的所有 Symbol 属性的键名。

Object.getOwnPropertySymbols(foo) //[Symbol()]
  • Reflect.ownKeys(obj)
Reflect.ownKeys()返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。

Reflect.ownKeys(foo) //[ 'age', 'name', Symbol() ]

对象的新增方法

Object.is()

ES6 提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。

Object.is('foo', 'foo'), //true    
Object.is(+0, -0), //false    
Object.is(NaN, NaN), //true    
Object.is([], []) //false
不同之处只有两个:一是+0不等于-0,二是NaN等于自身。

Object.assign()

Object.assign()方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

let target = {
    a: 1
}

let source1 = {
    b: 2
}

let source2 = {
    c: 3
}
target //{ a: 1, b: 2, c: 3 }
但是Object.assign()方法实行的是浅拷贝,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。

Object.getOwnPropertyDescriptors()

ES5 Object.getOwnPropertyDescriptor()方法会返回某个对象属性的描述对象(descriptor)。ES2017 引入了Object.getOwnPropertyDescriptors()方法,返回指定对象所有自身属性(非继承属性)的描述对象。

let obj = {
    age: 20,
    name: 'David'
}
Object.getOwnPropertyDescriptor(obj, 'age')
//{
    value: 20,  
    writable: true,  
    enumerable: true,  
    configurable: true 
  }

Object.getOwnPropertyDescriptors(obj)

{
    age:{ 
            value: 20,     
            writable: true,     
            enumerable: true,     
            configurable: true 
        },  
    name:{ 
            value: 'David',     
            writable: true,     
            enumerable: true,    
            configurable: true 
        }
}

__proto__属性、Object.setPrototypeOf()、Object.getPrototypeOf() 

JavaScript语言的对象继承是通过原型链实现的。ES6 提供了更多原型对象的操作方法。

__proto__属性
__proto__属性(前后各两个下划线),用来读取或设置当前对象的prototype对象。 

const obj = {
  method: function() { ... }
};
obj.__proto__ = someOtherObj;

Object.setPrototypeOf()

Object.setPrototypeOf()方法的作用与__proto__相同,用来设置一个对象的prototype对象,返回参数对象本身

Object.setPrototypeOf(obj,someOtherObj)

Object.getPrototypeOf()

该方法与Object.setPrototypeOf()方法配套,用于读取一个对象的原型对象。
Object.getPrototypeOf(obj)

Object.entries()

Object.entries()方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。

Object.entries(foo) //[ [ 'age', 20 ], [ 'name', 'David' ] ]

Object.fromEntries()

Object.fromEntries()方法是Object.entries()的逆操作,用于将一个键值对数组转为对象。

Object.fromEntries([
    ['age', 20],
    ['name', 'David']
])
//{age:20,name:'David'}