一、对象的定义
对象为一组属性(和方法)的无序集合。
let person = {
name: "zs",
age: 21,
sayName() {
console.log(this.name);
}};
这个例子创建了一个名为person的对象,它具有两个属性(name、age),以及一个方法(sayname())。
二、对象的属性
属性分为两种:数据属性和访问器属性。用来描述属性的特征的叫内部特性,内部特性一般用两个中括号括起来,如: [[Enumerable]] (可枚举性)。
1、数据属性
数据属性包含数据值。数据属性有四个特性:
- [[Configurable]]:可配置性,表示属性是否可以通过delete删除并重新定义,默认true。
- [[Enumerable]]:可枚举性,表示属性是否可以通过for-in循环返回,默认true。
- [[Writable]]:表示属性是否可以被修改,默认true。
- [[Value]]:表示属性实际的值,默认值为undefined。
2、访问器属性
访问器属性不包含数据值,他们包含一个获取(getter)函数和一个设置(setter)函数,这两个函数也并不是必须的。访问器属性有四个特性:
- [[Configurable]]:可配置性,表示属性是否可以通过delete删除并重新定义,默认true。
- [[Enumerable]]:可枚举性,表示属性是否可以通过for-in循环返回,默认true。
- [[Get]]:获取函数,读取属性时调用,会返回一个值,默认值为undefined。
- [[Set]]:设置函数,写入属性时调用并传入新值,默认值为undefined。
访问器属性使用场景:设置一个对象的属性值,会导致一些其它变化发生。如果想要定义一个访问器属性,不能直接定义,必须采用Object.defineProperty(),如将下列book例子中的属性year定义为访问器属性:
let book={
year_:2017, //year_中的下划线常用来表示该属性不希望在对象方法的外部访问
edition:1
};
Object.defineProperty(book,"year",{
get(){
return this.year_;
},
set(){
if(setValue>2017){
this.year_=newValue;
this.edition+=setValue-2017;
}
}
})
book.year=2018;
console.log(book.edition); //2
3、合并对象
合并,即将源对象的属性复制给目标对象。ES6为合并对象提供了Object.assign()方法,这个方法接受一个目标对象,和一个或多个源对象。
let dest,src,res;
dest={};
src={name:'zs'};
res=Object.assign(dest,src);
console.log(dest===res); //true(从一个对象到另一个对象的复制操作,复制的值其实是一个指针,它指向堆内存中的对象,因此两个变量都指向同一个对象。)
console.log(dest!==src); //true
获取函数和设置函数无法进行合并操作,即使赋了,也只是一个静态值。 若需要合并的多个源对象中有相同的属性,则后面的属性值会覆盖前面的。
4、ES6操作定义对象的新增语法糖
1、属性名和变量名一样时,可简写,只写变量名。
let name='zs';
let person={
name //只写变量名,自动被解释为使用同名属性键;等同于name:name。
}
console.log(person.name) //{name:'zs'}
2、属性值可计算
要想使用变量来作为属性值,可以使用中括号语法来添加属性。
const name = "name";
const age = "age";
let uniqueToken = 0;
function getUniqueKey(key) {
return `${key}_${uniqueToken++}`; //模板字符串中可采用${}进行字符串插值,即可插入一个变量
}
let person = {
[getUniqueKey(name)]: "zs", //这里的[]包围的属性键,在运行时将作为表达式而不是字符串来处理
[getUniqueKey(age)]: 21
};
console.log(person); //{ name_0: 'zs' , age_1: 21 }
3、对象中的方法名可简写
let person = {
sayName(){ //原本应写为:sayName:function(){ }
console.log('zs');
}
}