Accessor Properties
It is not possible to define an accessor property explicitly; you must use Object.defineProperty().
// Define object with pseudo-private member 'year_'// and public member 'edition'let book = {year_: 2017,edition: 1};Object.defineProperty(book, "year", {get() {return this.year_;},set(newValue) {if (newValue > 2017) {this.year_ = newValue;this.edition += newValue - 2017;}}});Object.defineProperty(book, "aaa", {value: 0});book.year = 2018;console.log(book.edition); // 2
拓展:Vue数据响应式
Defining Multiple Properties
用Object.defineProperties()定义多个properties
let book = {};Object.defineProperties(book, {year_: {value: 2017},edition: {value: 1},year: {get() {return this.year_;},set(newValue) {if (newValue > 2017) {this.year_ = newValue;this.edition += newValue - 2017;}}}});
getter / setter
let obj = {b: 'h',get a(){return 0;},set a(value){this.b = value;}}obj.a // 0obj.a = "hello"obj.b // "hello"
Object.assign()
相同属性会覆盖
dest = { id: 'dest' };result = Object.assign(dest, { id: 'src1', a: 'foo' }, { id: 'src2', b: 'bar' });// Object.assign will overwrite duplicate properties.console.log(result); // { id: src2, a: foo, b: bar }
getter/setter
/*** Getters and setters*/dest = {set a(val) {console.log('Invoked dest setter with param ${val}');}};src = {get a() {console.log('Invoked src getter');return 'foo';}};Object.assign(dest, src);// Invoked src getter// Invoked dest setter with param foo// Since the setter does not perform an assignment,// no value is actually transferredconsole.log(dest); // { set a(val) {...} }
Error handling
dest = {};src = {a: 'foo',get b() {// Error will be thrown when Object.assign()// invokes this getter.throw new Error();},c: 'bar'};try {Object.assign(dest, src);} catch(e) {}// Object.assign() has no way of rolling back already performed changes,// so set operations already performed on the destination object before// the error is thrown remain:console.log(dest); // { a: foo }
Object.is()
比较两个值是否相同
Object.is(true, 1) // falseObject.is({}, {}) // falseObject.is("2", 2) // false// Correct 0, -0, +0 equivalence/nonequivalence:Object.is(+0, -0) // falseObject.is(+0, 0) // trueObject.is(-0, 0) // false// Correct NaN equivalence:Object.is(NaN, NaN) // true
Enhanced Object Syntax
属性简写
let name = 'Matt';let person = {name // name:name简写};console.log(person); // { name: 'Matt' }
计算属性
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' }
方法简写
let person = {// sayName: function(name) {} 简写sayName(name) {console.log('My name is ${name}');}};person.sayName('Matt'); // My name is Matt
计算属性和方法简写混合使用
const methodKey = 'sayName';let person = {[methodKey](name) {console.log('My name is ${name}');}}person.sayName('Matt'); // My name is Matt
解构赋值
let person = {name: 'Matt',age: 27};let { name, age } = person;console.log(name); // Mattconsole.log(age); // 27
let personName, personAge;let person = {name: 'Matt',age: 27};// 注意括号({name: personName, age: personAge} = person);console.log(personName, personAge); // Matt, 27
解构传参
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');// ['1st', { name: 'Matt', age: 27 }, '2nd']// 'Matt', 27printPerson2('1st', person, '2nd');// ['1st', { name: 'Matt', age: 27 }, '2nd']// 'Matt', 27
