面向对象编程 -- 理解对象3
一、增强的对象语法
1.属性值简写
// ECMAScript 6 为定义和操作对象新增了很多及其有用的语法糖特性。
let name = 'Matt';
let person = {
name: name
};
console.log(person); // { name: 'Matt' }
// 为此,简写属性名语法出现了。
let name = 'Matt';
let person = {
name
};
console.log(person); // { name: 'Matt' }
// 代码压缩程序会在不同作用域保留属性名,以防止找不到引用。
function makePerson(name) {
return {
name
};
}
let person = makePerson('Matt');
console.log(person.name); // Matt
2.可计算属性
// 在引入可计算属性之前,如果想使用变量的值作为属性,那么必须先声明对象,然后使用中括号语法来添加属性。
const nameKey = 'name';
const ageKey = 'age';
const jobKey = 'job';
let person = {};
person[nameKey] = 'Matt';
person[ageKey] = 27;
person[jobKey] = 'Software engineer';
console.log(person); // { name: 'Matt', age: 27, job: 'Software engineer' }
// 有了可计算属性,就可以在对象字面量中完成动态属性赋值。
const nameKey = 'name';
const ageKey = 'age';
const jobKey = 'job';
let person = {
[nameKey]: 'Matt',
[ageKey]: 27,
[jobKey]: 'Software engineer'
};
console.log(person); // { name: 'Matt', age: 27, job: 'Software engineer' }
// 因为被当作 JavaScript 表达式求值,所以可计算属性本身可以是复杂的表达式,在实例化时再求值:
const nameKey = 'name';
const ageKey = 'age';
const jobKey = 'job';
let uniqueToken = 0;
function getUniqueKey(key) {
return `${key}_${uniqueToken++}`;
}
let person = {
[getUniqueKey(nameKey)]: 'Matt',
[getUniqueKey(ageKey)]: 27,
[getUniqueKey(jobKey)]: 'Software engineer'
};
console.log(person); // { name_0: 'Matt', age_1: 27, job_2: 'Software engineer' }
3.简写方法名
// 在给对象定义方法时,通常都要写一个方法名、冒号,然后再引用一个匿名函数表达式
let person = {
sayName: function(name) {
console.log(`My name is ${name}`);
}
};
person.sayName('Matt'); // My name is Matt
// 新的简写方法的语法遵循同样的模式,但开发者要放弃给函数表达式命名。
let person = {
sayName(name) {
console.log(`My name is ${name}`);
}
};
person.sayName('Matt'); // My name is Matt
// 简写方法名对获取函数和设置函数也是使用的:
let person = {
name_: '',
get name() {
return this.name_;
},
set name(name) {
this.name_ = name;
},
sayName() {
console.log(`My name is ${this.name_}`);
}
};
person.name = 'Matt';
person.sayName(); // My name is Matt
// 简写方法名与可计算属性键相互兼容:
const methodKey = 'sayName';
let person = {
[methodKey](name) {
console.log(`My name is ${name}`);
}
}
person.sayName('Matt'); // My name is Matt
二、对象解构
// ECMAScript 6 新增了对象解构语法,可以在一条语句中使用嵌套数据实现一个或多个赋值操作。
// 不使用对象解构
let person = {
name: 'Matt',
age: 27
};
let personName = person.name,
personAge = person.age;
console.log(personName); // Matt
console.log(personAge); // 27
// 使用对象解构,效果同上面
let person = {
name: 'Matt',
age: 27
};
let { name: personName, age: personAge } = person;
console.log(personName); // Matt
console.log(personAge); // 27
// 如果想让变量直接使用属性的名称,那么可以使用简写语法
let person = {
name: 'Matt',
age: 27
};
let { name, age } = person;
console.log(name); // Matt
console.log(age); // 27
// 解构赋值不一定与对象的属性匹配。
let person = {
name: 'Matt',
age: 27
};
let { name, job } = person;
console.log(name); // Matt
console.log(job); // undefined
// 也可以在解构的同时定义默认值
let person = {
name: 'Matt',
age: 27
};
let { name, job='Software engineer' } = person;
console.log(name); // Matt
console.log(job); // Software engineer
1.嵌套解构
// 解构对于引用嵌套的属性或赋值目标没有限制。
let person = {
name: 'Matt',
age: 27,
job: {
title: 'Software engineer'
}
};
let personCopy = {};
({
name: personCopy.name,
age: personCopy.age,
job: personCopy.job
} = person);
// 由于对象引用已分配给personCopy,因此更改属性
// 在person.job对象中,将影响到personCopy:
person.job.title = 'Hacker'
console.log(person);
// { name: 'Matt', age: 27, job: { title: 'Hacker' } }
console.log(personCopy);
// { name: 'Matt', age: 27, job: { title: 'Hacker' } }
// 解构赋值可以使用嵌套解构,以匹配嵌套的属性:
let person = {
name: 'Matt',
age: 27,
job: {
title: 'Software engineer'
}
};
// 声明“title”变量并将person.job.title的值赋给它
let { job: { title }} = person;
console.log(title); // Software engineer
2.参数上下文匹配
// 在函数参数列表中也可以进行解构赋值。
let person = {
name: 'Matt',
age: 27
};
function printPerson(foo, {name, age}, bar) {
console.log(arguments);
console.log(name, age);
}
function printPerson2(foo, {name: personName, age: personAge}, bar) {
console.log(arguments);
console.log(personName, personAge);
}
printPerson('1st', person, '2nd');
printPerson2('1st', person, '2nd');