一、对象
1、对象字面量
属性的简洁表示
const age = 12;
const name = "Amy";
const person = {age, name};
person //{age: 12, name: "Amy"}
//等同于
const person = {age: age, name: name}
方法名的简写
const person = {
sayHi(){
console.log("Hi");
}
}
person.sayHi(); //"Hi"
//等同于
const person = {
sayHi:function(){
console.log("Hi");
}
}
person.sayHi();//"Hi"
属性名表达式
//ES6允许用表达式作为属性名,但是一定要将表达式放在方括号内。
const obj = {
["he"+"llo"](){
return "Hi";
}
}
obj.hello(); //"Hi"
//属性的简洁表示法和属性名表达式不能同时使用,否则会报错
const hello = "Hello";
const obj = {
[hello]
};
obj //SyntaxError: Unexpected token }
const hello = "Hello";
const obj = {[hello+"2"]:"world"};
obj //{Hello2: "world"}
2、对象扩展运算符
基本用法
let person = {name: "Amy", age: 15};
let someone = { ...person };
someone; //{name: "Amy", age: 15}
合并对象
let age = {age: 15};
let name = {name: "Amy"};
let person = {...age, ...name};
person; //{age: 15, name: "Amy"}
注意点
//自定义的属性在拓展运算符后面,则拓展运算符对象内部同名的属性将被覆盖掉。
let person = {name: "Amy", age: 15};
let someone = { ...person, name: "Mike", age: 17};
someone; //{name: "Mike", age: 17}
3、对象的新方法
Object.assign(target, source_1, ···)
用于将源对象的所有可枚举属性复制到目标对象中。
let target = {a: 1};
let object2 = {b: 2};
let object3 = {c: 3};
Object.assign(target,object2,object3);
// 第一个参数是目标对象,后面的参数是源对象
target; // {a: 1, b: 2, c: 3
如果该函数只有一个参数,当参数为对象时,直接返回该对象;当参数不是对象时,会先将参数转为对象然后返回,因为 null 和 undefined 不能转化为对象,所以会报错。
//assign 的属性拷贝是浅拷贝:
let sourceObj = { a: { b: 1}};
let targetObj = {c: 3};
Object.assign(targetObj, sourceObj);
targetObj.a.b = 2;
sourceObj.a.b; // 2
//同名属性替换
targetObj = { a: { b: 1, c:2}};
sourceObj = { a: { b: "hh"}};
Object.assign(targetObj, sourceObj);
targetObj; // {a: {b: "hh"}}
//数组的处理会将数组处理成对象,所以先将 [2,3] 转为 {0:2,1:3} ,然后再进行属性复制,所以源对象的 0 号属性覆盖了目标对象的 0。
Object.assign([2,3], [5]); // [5,3]
Object.is(value1, value2)
用来比较两个值是否严格相等,与(===)基本类似。
//基本用法
Object.is("q","q"); // true
Object.is(1,1); // true
Object.is([1],[1]); // false
Object.is({q:1},{q:1}); // false
//与(===)的区别
//一是+0不等于-0
Object.is(+0,-0); //false
+0 === -0 //true
//二是NaN等于本身
Object.is(NaN,NaN); //true
NaN === NaN //false
二、函数
1、函数参数的扩展
默认参数
function fn(name,age=17){
console.log(name+","+age);
}
fn("Amy",18); // Amy,18
fn("Amy",""); // Amy,
fn("Amy"); // Amy,17
不定参数
function f(...values){
console.log(values.length);
}
f(1,2); //2
f(1,2,3,4); //4
2、箭头函数
参数 => 函数体
var f = (a,b) => {
let result = a+b;
return result;
}
f(6,2); // 8
//当箭头函数要返回对象的时候,为了区分于代码块,要用 () 将对象包裹起来
// 报错
var f = (id,name) => {id: id, name: name};
f(6,2); // SyntaxError: Unexpected token :
// 不报错
var f = (id,name) => ({id: id, name: name});
f(6,2); // {id: 6, name: 2}
箭头函数体中的 this 对象,是定义函数时的对象,而不是使用函数时的对象
三、class类
1、基本用法
类定义
// 匿名类
let Example = class {
constructor(a) {
this.a = a;
}
}
// 命名类
let Example = class Example {
constructor(a) {
this.a = a;
}
}
类声明
class Example {
constructor(a) {
this.a = a;
}
}
注意要点
类定义不会被提升,必须在访问前对类进行定义,类中方法不需要 function 关键字,方法间不能加分号。
new Example();
class Example {}
类的实例化
//class 的实例化必须通过 new 关键字。
class Example {}
let exam1 = Example();
// Class constructor Example cannot be invoked without 'new'
2、decorator
类修饰
//第一个参数 target,指向类本身。
function testable(target) {
target.isTestable = true;
}
@testable
class Example {}
Example.isTestable; // true
//多个参数——嵌套实现
function testable(isTestable) {
return function(target) {
target.isTestable=isTestable;
}
}
@testable(true)
class Example {}
Example.isTestable; // true
方法修饰
//3个参数:target(类的原型对象)、name(修饰的属性名)、descriptor(该属性的描述对象)。
class Example {
@writable
sum(a, b) {
return a + b;
}
}
function writable(target, name, descriptor) {
descriptor.writable = false;
return descriptor; // 必须返回
}
//修饰器执行顺序,由外向内进入,由内向外执行。
class Example {
@logMethod(1)
@logMthod(2)
sum(a, b){
return a + b;
}
}
function logMethod(id) {
console.log('evaluated logMethod'+id);
return (target, name, desctiptor) => console.log('excuted logMethod '+id);
}
// evaluated logMethod 1
// evaluated logMethod 2
// excuted logMethod 2
// excuted logMethod 1
3、封装与继承
-
getter/setter
-
extends
class Child extends Father {...}
-
super
-
注意要点
四、模块
ES6 的模块化分为导出(export) @与导入(import)两个模块。
1、以对象属性的形式export和import
一般形式
//export.js
export let x=1;
export let y=2;
import{x,y} from "./export.js"
console.log(x,y)//输出x=1,y=2
函数名的形式
//export.js
export function x(){
}
import {x} from "./export.js";
console.log(x)//输出的为x函数
import as
/export.js
export let x=1;
export let y=2;
//import.js
import * as myVar from "./export.js"
console.log(myVar.x)//输出为1
console.log(myVar.y)//输出为2
2、以模板的形式export和import
export
//export.js
export default let x=1;
import
import x from "./export.js";
console.log(x) //输出的是x
五、async异步
//name: 函数名称。
//param: 要传递给函数的参数的名称。
//statements: 函数体语句。
async function name([param[, param[, ... param]]]) { statements }
返回值
async function helloAsync(){
return "helloAsync";
}
console.log(helloAsync()) // Promise {<resolved>: "helloAsync"}
helloAsync().then(v=>{
console.log(v); // helloAsync
})
async表达式
function testAwait(){
return new Promise((resolve) => {
setTimeout(function(){
console.log("testAwait");
resolve();
}, 1000);
});
}
async function helloAsync(){
await testAwait();
console.log("helloAsync");
}
helloAsync();
// testAwait
// helloAsync
await针对所跟不同表达式的处理方式:
function testAwait(){
console.log("testAwait");
}
async function helloAsync(){
await testAwait();
console.log("helloAsync");
}
helloAsync();
// testAwait
// helloAsync