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 // 0
obj.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 transferred
console.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) // false
Object.is({}, {}) // false
Object.is("2", 2) // false
// Correct 0, -0, +0 equivalence/nonequivalence:
Object.is(+0, -0) // false
Object.is(+0, 0) // true
Object.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); // Matt
console.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', 27
printPerson2('1st', person, '2nd');
// ['1st', { name: 'Matt', age: 27 }, '2nd']
// 'Matt', 27