JS字典系列|对象篇

236 阅读3分钟

一、对象属性

1.1 数据属性

数据属性包含一个保存数据值的位置。值会从这里读取写入。数据属性有四个描述行为。

1.1.1 [[Configurable]]

表示属性是否可以通过delete删除并重新定义,是否可以修改它的特性,以及是否可以把它设置为访问器属性,默认为true
此属性修改之后就不可再改回去了!!!

1.1.2 [[Enumberable]]

表示属性是否可以通过for-in循环返回,默认为true

1.1.3 [[Writable]]

表示属性的是否可以被修改。默认为true

1.1.4 [[Value]]

表示包含属性实际的值的值。

要修改属性的默认特性,只能使用v

let person = {}
Object.defineProperty(person,"name",{
    writable:false,
    value:"Jack"
});
console.log(person.name);//"Jack"
person.name = "Greg";
console.log(person.name);//"Jack"

如上面所示,将writable改为了false,故不可以修改了。

1.2 访问器属性

访问器属性不包含数据值,它包含有一个获取(getter)和设置(setter)。在写入访问器属性时,会调用设置函数并传入新值。

1.2.1 [[Configurable]]

表示属性是否可以通过delete删除并重新定义,是否可以修改它的特性,以及是否可以把它设置为访问器属性,默认为true
此属性修改之后就不可再改回去了!!!

1.2.2 [[Enumberable]]

表示属性是否可以通过for-in循环返回,默认为true

1.2.3 [[Get]]

获取函数,在读取时调用。默认为undefined

1.2.4 [[Set]]

设置函数,在写入时调用。默认为undefined

let book = {
    year_:2017,
    edition:1
}
Object.defineProperty(book,"year",{
    get(){
        return this.year_;
    },
    set(value){
        if(value>2017){
            this.year_ = value;
            this.edition += value - 2017
        }
    }
});
book.year = 2018;
console.log(book.edition);//2

二、常用原型函数

2.1 Object.defineProperty() 定义属性

具体用法见上文。

2.2 Object.getOwnPropertyDescriptor

该方法用于读取指定属性以及属性描述符。

let book = {
    year_:2017,
    edition:1
}
Object.defineProperty(book,"year",{
    get(){
        return this.year_;
    },
    set(value){
        if(value>2017){
            this.year_ = value;
            this.edition += value - 2017
        }
    }
});
let des = Object.getOwnPropertyDescriptor(book,"year_")
console.log(des.value)//2017
console.log(des.configurable)//false
console.log(typeof des.get)//"undefined"
let des = Object.getOwnPropertyDescriptor(book,"year")
console.log(des.value)//undefined
console.log(des.configurable)//false
console.log(typeof des.get)//"function"

三、常用方法

3.1 Object.assign() 合并对象

此方法为ES6新增方法,该方法可接受一个目标对象以及一个或多个源对象作为参数。此方法调用之后,以字符串和符号为键的属性会被复制。对每个符合条件的属性,这个方法会使用源对象上的[[Get]]取得属性的值,然后使用目标对象的[[Set]]设置属性的值。

基本复制:

    let dest={} 
    let src = {id:'src'}
    let result = Object.assign(dest,src) ;//dest 为目标对象,src为源对象
    console.log(dest===result);//true
    console.log(dest!==result);//true
    console.log(result);//{id:'src'}
    console.log(dest); //{id:'src'}

多个源对象:

dest = {}
result = Object.assign(dest,{a:'foo'},{b:'bar'})
console.log(result) //{a:foo, b:bar}

获取函数和设置函数

dest = {
    set a(val){
        console.log(val)
    }
}
src = {
    get a(){
        return 'foo'
    }
}

Object.assign(dest,src)

上面这一段首先使用了scr上的get获取了值并传入“foo”,再调用dest上的set,生成属性的值。

3.2 解构

3.2.1 普通解构

let person = {
    name:'Matt',
    age:27
}

let {name,age} = person

console.log(name)//Matt
console.log(age)//27


let {name:personName,age:personAge} = person

console.log(personName)//Matt
console.log(personAge)//27


//也可以解构赋值时同时定义默认值

let {name, job='student'} = person
console.log(job)//student

3.2.2 嵌套解构

let person = {
    name:'Matt',
    age:27,
    job:{
        title:'student'
    }
}

let {job:{title}} = person//student

在外层属性没有定义的情况下不能使用此方法。

3.2.3 部分解构

需要注意的是,涉及多个属性的解构赋值时,如果一个赋值出错,则整个表达式只会完成一部分。