属性的简洁表示法
ES6 允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
如下:
const apple = 'apple'
const banana = 'banana'
const fruit = {
apple,
banana
}
console.log(fruit);
// {apple: "apple", banana: "banana"}
function fn(m,n){
return {m,n}
}
// 上面的写法和下面的写法意义相同
function fn(x,y){
return {x:x,y:y}
}
方法的简洁写法
直接看代码一目了然,没啥好说的
const obj ={
name:'ann',
say(){
console.log('name');
}
}
// 相当于
const obj ={
name:'ann',
say:function(){
console.log('name');
}
}
简洁写法的属性名总是字符串,所以有时候你用关键字作为属性名也是可以的,但是尽量不要出现这种情况
定义对象属性的两种方式
方法一是直接用标识符作为属性名
方法二是用表达式作为属性名,这时要将表达式放在方括号之内。
但是,如果使用字面量方式定义对象(使用大括号),在 ES5 中只能使用方法一(标识符)定义属性。
可在对象字面量的定义模式里面使用某个变量作为某个属性的名称
表达式还可以用于定义方法名。
注意,属性名表达式与简洁表示法,不能同时使用,会报错
注意,属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[object Object],这一点要特别小心。
对象属性的可枚举
对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。
Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。
let obj = {
name:'ann',
age:'18'
}
Object.getOwnPropertyDescriptor(obj,'age')
console.log(Object.getOwnPropertyDescriptor(obj,'age'));
描述对象的enumerable属性,称为“可枚举性”,如果该属性为false,就表示某些操作会忽略当前属性。
目前,有四个操作会忽略enumerable为false的属性。
- for…in循环:只遍历对象自身的和继承的可枚举的属性
- Object.keys():返回对象自身的所有可枚举的属性的键名
- JSON.stringify():只 串行化 对象自身的可枚举的属性
- Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。
ES6 遍历对象属性的5种方法
- for…in for…in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)
- Object.keys(obj) Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
- Object.getOwnPropertyNames(obj) Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
- Object.getOwnPropertySymbols(obj) Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。
- Reflect.ownKeys(obj) Reflect.ownKeys返回一个数组,包含对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
Object.keys(obj)
const arr = Object.keys(obj)
console.log(arr);
Object.getOwnPropertyNames(obj)
var obj = { 0: "a", 1: "b", 2: "c"};
console.log(Object.getOwnPropertyNames(obj).sort()); // ["0", "1", "2"]
Object.getOwnPropertySymbols(obj)
var obj = {};
var a = Symbol("a");
var b = Symbol.for("b");
obj[a] = "localSymbol";
obj[b] = "globalSymbol";
var objectSymbols = Object.getOwnPropertySymbols(obj);
console.log(objectSymbols.length); // 2
console.log(objectSymbols) // [Symbol(a), Symbol(b)]
console.log(objectSymbols[0]) // Symbol(a)
对象的原型对象属性
函数里的this关键字总是指向调用该函数所在的当前对象,ES6 又新增了另一个类似的关键字super,指向当前对象的原型对象。
const proto = {
characters:'chain'
}
const obj ={
characters:"mix",
find(){
return super.characters
}
}
Object.setPrototypeOf(obj,proto) //设置obj的原型对象为proto
console.log(obj.find()); //chain
对象obj.find()方法之中,通过super.foo引用了原型对象proto的foo属性。
注意,super关键字表示原型对象时,只能用在对象的方法之中,用在其他地方都会报错。
左边三种super的用法都会报错,因为对于 JavaScript 引擎来说,这里的super都没有用在对象的方法之中。
第一种写法是super用在属性里面
第二种和第三种写法是super用在一个函数里面,然后赋值给foo属性。
目前,只有对象方法的简写法可以让 JavaScript 引擎确认,定义的是对象的方法,所以这玩意的使用环境苛刻, 现在可以少用一些
JavaScript 引擎内部,super.foo等同于Object.getPrototypeOf(this)
对象的扩展运算符赋值
扩展运算符(…)可用于对象中
解构赋值要求等号右边是一个对象,所以如果等号右边是undefined或null,就会报错,因为它们无法转为对象
扩展运算符的解构赋值,不能复制继承自原型对象的属性
对象的扩展运算符(…)在赋值符号右侧, 用于取出参数对象的所有可遍历属性,拷贝到左侧的当前对象之中。
let x = {one:1,two:2}
let y = {...x}
console.log(y);
// {one: 1, two: 2}
上面的方法可以成为一个复制对象的简便方法
如果扩展运算符后面不是对象,则会自动将其转为对象。
扩展运算符后面是整数1,会自动转为数值的包装对象Number{1}。由于该对象没有自身属性,所以返回一个空对象。其他的一个道理