ES6—对象
作者:米书林
参考文章:《菜鸟教程》、《 ECMAScript 6 入门》(阮一峰)
1.属性的简洁表示法
简介:ES6允许对象的属性直接写变量,这时候属性名是变量名,属性值是变量值。
let name = "小明",
age = 12;
let student = {name,age};
console.log(student); // {name: "小明", age: 12}
// 相当于
let student = {name:name,age:age};
变量的值发生改变不会影响到对象,即上面修改age = 13,student.age仍然等于12
2.方法的简洁表示法
ES5中给对象定义方法,需要先定义一个函数,再把函数赋值给对象的属性;ES6可以把函数声明function去除,直接定义一个方法
let sex = "男"
let person = {
name:"小明",
age:12
}
let student = {
...person,
sex,
study(a){
return `你好,我是${this.name},今年${this.age}岁,我正在学习${a}`
}
}
console.log(student); // {name: "小明", age: 12, sex: "男", study: ƒ}
student.study("语文") // "你好,我是小明,今年12岁,我正在学习语文"
// 等同于
let student = {
name:"小明",
age:12,
sex:"男",
study:function(a){
return "你好,我是"+this.name+",今年"+this.age+"岁,我正在学习"+a;
}
}
如果是Generator 函数,则要在前面加一个星号
const obj = {
* myGenerator() {
yield 'hello world';
}
};
//等同于
const obj = {
myGenerator: function* () {
yield 'hello world';
}
};
用途
1.返回函数的结果
function f(x, y) {
return {x, y};
}
// 等同于
function f(x, y) {
return {x: x, y: y};
}
f(1, 2) // Object {x: 1, y: 2}
2.CommonJS 模块输出一组变量
let ms = {};
function getItem (key) {
return key in ms ? ms[key] : null;
}
function setItem (key, value) {
ms[key] = value;
}
function clear () {
ms = {};
}
module.exports = { getItem, setItem, clear };
3.属性名表达器
js属性表达的方式
第一种:.
第二种:[""]
let obj = {name:"小明"};
obj.name; // "小明"
obj["name"] // 小明
属性名表达式
简介:ES6允许用表达式作为属性名,但是一定要将表达式放在方括号内
const obj = {
["he"+"llo"](){
return "Hi";
}
}
obj.hello(); //"Hi"
let lastWord = 'last word';
const a = {
'first word': 'hello',
[lastWord]: 'world'
};
a['first word'] // "hello"
a[lastWord] // "world"
a['last word'] // "world"
4.对象的拓展运算符
1.解构赋值
基本用法
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 ,c:5};
console.log(z); // a: 3, b: 4 ,c:5
注意事项:
1.等号右边是一个对象
let { ...a } = null; // 报错
let { ...a } = true; // {}
let { ...a } = undefined; // 报错
let { ...a } = NaN; // {}
let { ...a } = 1; // {}
let { ...a } = "12"; // {0: "1", 1: "2"}
2.解构赋值必须是最后一个参数,否则会报错。
let { ...x, y, z } = { a:0,x: 1, y: 2, z: 3}; // 句法错误 Rest element must be last element
let { x, ...y, ...z } = { a:0,x: 1, y: 2, z: 3}; // 句法错误 Rest element must be last element
3.解构赋值的拷贝是浅拷贝
let obj = {name:"张三",hobby:{h1:"篮球",h2:"排球"}}
let {...obj1} = obj;
obj.hobby.h1 = "乒乓球";
obj1;
// {name: "张三", hobby: {h1: "乒乓球", h2: "排球"}}
4.扩展运算符的解构赋值,不能复制继承自原型对象的属性
let o1 = { a: 1 };
let o2 = { b: 2 };
o2.__proto__ = o1;
let { ...o3 } = o2;
o3 // { b: 2 }
o3.a // undefined
4.对象方法的name属性
函数的name
属性,返回函数名。对象方法也是函数,因此也有name
属性
let obj = {
name:"张三",
smoking(){
return `大家好,我是${this.name},我不会抽烟`
}
}
obj.smoking.name // "smoking"
如果对象的方法使用了取值函数(getter)和存值函数(setter),则name属性不是在该方法上面,而是该方法的属性的描述对象的get和set属性上面,返回值是方法名前加上get和set。
const obj = {
get foo() {},
set foo(x) {}
};
obj.foo.name
// TypeError: Cannot read property 'name' of undefined
const descriptor = Object.getOwnPropertyDescriptor(obj, 'foo');
descriptor.get.name // "get foo"
descriptor.set.name // "set foo"
有两种特殊情况:bind
方法创造的函数,name
属性返回bound
加上原函数的名字;Function
构造函数创造的函数,name
属性返回anonymous
。
(new Function()).name // "anonymous"
var doSomething = function() {
// ...
};
doSomething.bind().name // "bound doSomething"
如果对象的方法是一个 Symbol 值,那么name属性返回的是这个Symbol 值的描述
。
const key1 = Symbol('description');
const key2 = Symbol();
let obj = {
[key1]() {},
[key2]() {},
};
obj[key1].name // "[description]"
obj[key2].name //
属性的遍历
(1)for...in
遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)的key值
(2)Object.keys(obj)
遍历对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名,返回一个数组
(3)Object.getOwnPropertyNames(obj)
遍历对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名,返回一个数组
(4)Object.getOwnPropertySymbols(obj)
遍历对象自身的所有 Symbol 属性的键名,返回一个数组
(5)Reflect.ownKeys(obj)
遍历对象自身的所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举,返回一个数组。
let sy = Symbol("h");
let obj = {name:"abc",[sy]:"dd",arr:[1,2,3],};
// for...in遍历
for(key in obj){
console.log(key);
}
// name
// arr
Object.keys(obj)
// ["name", "arr"]
Object.getOwnPropertyNames(obj)
// ["name", "arr"]
Object.getOwnPropertySymbols(obj)
// [Symbol(h)]
Reflect.ownKeys(obj)
// ["name", "arr", Symbol(h)]
对象的super关键字
this
关键字指向函数所在的当前对象,super
关键字指向当前对象的原型对象
const proto = {
foo: 'hello'
};
const obj = {
foo: 'world',
find() {
return super.foo;
}
};
Object.setPrototypeOf(obj, proto);
obj.find() // "hello"
super
关键字表示原型对象时,只能用在对象的简写方法之中,用在其他地方都会报错。
// 报错
const obj = {
foo: super.foo
}
// 报错
const obj = {
foo: () => super.foo
}
// 报错
const obj = {
foo: function () {
return super.foo
}
}