面向对象编程 -- 理解对象3

一、增强的对象语法

1.属性值简写

// ECMAScript 6 为定义和操作对象新增了很多及其有用的语法糖特性。

let name = 'Matt';

let person = {
  name: name
};

console.log(person);  // { name: 'Matt' }

属性值简写 08.png

// 为此,简写属性名语法出现了。

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 09.png

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' }

可计算属性 03.png

// 有了可计算属性,就可以在对象字面量中完成动态属性赋值。

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' } 

可计算属性 04.png

3.简写方法名

// 在给对象定义方法时,通常都要写一个方法名、冒号,然后再引用一个匿名函数表达式

let person = {
  sayName: function(name) {
    console.log(`My name is ${name}`);
  }
};

person.sayName('Matt');  // My name is Matt

简写方法名 05.png

// 新的简写方法的语法遵循同样的模式,但开发者要放弃给函数表达式命名。

let person = {
  sayName(name) {
    console.log(`My name is ${name}`);
  }
};

person.sayName('Matt');  // My name is Matt

简写方法名2 06.png

// 简写方法名对获取函数和设置函数也是使用的:

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

简写方法名3 07.png

// 简写方法名与可计算属性键相互兼容:

const methodKey = 'sayName';

let person = {
  [methodKey](name) {
    console.log(`My name is ${name}`);
  }
} 

person.sayName('Matt');  // My name is Matt

简写方法名4 08.png

二、对象解构

// ECMAScript 6 新增了对象解构语法,可以在一条语句中使用嵌套数据实现一个或多个赋值操作。


// 不使用对象解构
let person = {
  name: 'Matt',
  age: 27
};

let personName = person.name,
    personAge = person.age;

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

对象解构 09.png

// 使用对象解构,效果同上面
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 

对象解构2 10.png

// 解构赋值不一定与对象的属性匹配。


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

let { name, job } = person;

console.log(name);  // Matt
console.log(job);   // undefined

对象解构3 11.png

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


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

let { name, job='Software engineer' } = person;

console.log(name);  // Matt
console.log(job);   // Software engineer

对象解构4 12.png

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' } }

嵌套解构 13.png

// 解构赋值可以使用嵌套解构,以匹配嵌套的属性:

let person = {
  name: 'Matt',
  age: 27,
  job: {
    title: 'Software engineer'
  }
};

// 声明“title”变量并将person.job.title的值赋给它
let { job: { title }} = person;

console.log(title);  // Software engineer 

嵌套解构2 14.png

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');

参数上下文匹配15.png