ES6语法

for in 可以遍历对象,for of 不能遍历对象,只能遍历带有iterator接口的

for in 可以遍历对象,for of 不能遍历对象,只能遍历带有iterator接口的

这里指的是ES6相较于ES1~5的新增区别变化,并不是所有的JavaScript语法

letconst

ES6新增这两个关键字用于定义变量:

let

  1. let声明变量没有变量提升
  2. 是一个块级作用域
  3. 不能重复定义

const

其他特性与let相同,他是声明常量,一旦被声明,不允许被修改

解构赋值

  • 解构赋值是对赋值运算符的一种扩展

  • 它针对数组和对象来进行操作

  • 优点:代码书写上简洁易读

    letnode={
    	type:'iden',
    	name:'foo'
    }
    let {type,name} = node;
    console.log(type,name)
    //不完全解构可忽略
    let {a,...res} = obj;
    默认值
    let {a,b=20} = {a:20};
    //对数组解构
    let arr =[1,2,3];
    let [a,b,c] = arr; 
    console.log(a,b,c);
    //不完全结构
    let arr =[1,2,3];
    let [a,b] = arr; 
    console.log(a,b);
    //可嵌套
    let[a,[b],c] =[1,[2],3];

模板字符串

就是使用符号"`"用来定义字符串,插入的变量使用${}包裹
`id=${id}`

函数默认值和剩余参数

ES6写法

function add(a=10,b=20){
	return a+b;
}

函数的默认值也可以是一个函数

function add(a=10,b=func()){
	return a+b;
}

函数所有参数被arguments属性包含,这是一个为数组

这个就能得到任意数量的参数

剩余参数:由三个点...和一个紧跟着的具名参数指定...keys

function f(...keys){
	.........
}

最终的keys是一个数组

rest参数

ES6引入rest参数用于取代arguments

js
//以前获取全部参数:
function f(){
    log(arguments)
}
//es6语法
fuction f(...args){
    log(args)
}

扩展运算符...

剩余运算符:把多个独立的合并到一个数组中 扩展运算法:将一个数组分割,并将各个项作为分离的参数传给函数

比如说取最大值案例

//处理一般数据
const maxNum = Math.max(20,30); 
console.log(maxNum);
//处理数组
//处理数组中的最大值,使用apply
const arr=[10,20,50,30,90,100,40];
console.log(Math.max.apply(null,arr)
//es6扩展云算法更方便
console.log(Math.max(...arr))

使用这个还可以对对象使用,展开对象

const obj={
	name:'',
	age:18
}
const obj2={
	...obj
}

//3.将伪数组转为真正的数组
const divs =document.querySelectorAll('div') 
constdivArr=[...divs];
console.log(divArr)://arguments

es6的箭头函数

使用=>来定义function(){} 等于与()=>{} 
let add = function (a,b){
return a+b;
}

简化方式与Java的lamda表达式一样

a=>a;
(a,b)=>a+b;//这里一定不能省略()

注意

箭头函数没有this指向,箭头函数内部this只能通过查找作用域链来确定

改变函数指针的方式

call函数

call() 方法

  • 作用‌:立即调用函数,并显式指定 ‌**`this“**‌ 的指向,同时支持参数列表传递。

  • 语法‌:函数名.call(thisArg, arg1, arg2, ...)

  • ‌特点

    • 第一个参数为 ‌**this**‌ 的绑定对象,后续参数逐个传递‌。
    • 若 ‌**thisArg**‌ 为 nullundefined,默认指向全局对象(如浏览器中的 window)‌。
  • ‌示例

    function greet(a, b) { console.log(this.name, a + b); }
    const obj = { name: 'John' };
    greet.call(obj, 1, 2); // 输出:John 3

apply函数

apply() 方法

  • 作用‌:与 call() 类似,但参数以 ‌数组形式‌ 传递。

  • 语法‌:函数名.apply(thisArg, [argsArray])

  • ‌特点‌:

    • 适用于参数数量不确定或需要动态传递的场景,如数组计算‌。
    • 执行机制与 call() 一致,仅参数传递方式不同‌。
  • 示例:

    js
    greet.apply(obj, [3, 4]); // 输出:John 7

bind函数

bind() 方法

  • 作用‌:返回一个 ‌新函数‌,其 ‌**this‌ 永久绑定到指定对象,且可预设部分参数(‌柯里化**‌)。

  • 语法‌:函数名.bind(thisArg, arg1, arg2, ...)

  • ‌特点‌:

    • 不会立即执行‌,需手动调用返回的函数‌。
    • 常用于事件监听、回调函数等需要延迟执行的场景‌。
  • 示例‌:

    js
    const boundGreet = greet.bind(obj, 5);
    boundGreet(6); // 输出:John 11

核心区别总结

方法执行时机参数形式应用场景
call()立即执行参数列表明确参数数量时使用
apply()立即执行数组动态参数或数组操作时使用
bind()延迟执行参数列表/预设需要固定 this 的异步场景

bind函数使用最广,因为不会立即调用,而是返回一个函数

拓展对象方法

es6直接写入变量和函数,作为对象的属性和方法

const name='小马哥',age=20;
//原始写法
const person={
	name:name, 
	age:age,
	sayName:function(){
		//...
	}
}
//简写
const person={
	name, 
	age,
	sayName(){
		//...
	}
}

动态属性

const name='a'
const obj = {
	isshow:true,
	[name]:123,
	['f'+name]:452
}

is()

//is() ===
//比较两个值是否严格相等
consoLe.Log(NaN===NaN)
consoLe.Log(Object.is(NaN,NaN))

assign()

对象的合并

Object.assign(target,obj1,obj2,...)
let o =Object.assign({},{a:1},{b:2});

symbol

原始数据类型symbol,它表示是独一无二的值

const name=Symbol('name);
const name2=Symbol(name')
console.log(name1===name2)

最大用途一般用于定义对象的私有变量(这个属性没法被遍历,也不在keys里面)

let s1 = Symbol('s1');
console.log(s1); 
let obj = {};
obj[s1]=‘小马哥';
//取值
obj[s1]
//如果用symboL定义的对象中的变量,取值时一定要用[变量名]
//这个可以得到
let s = Object.getOwnPropertySymbols(obj); 
console.log(s)
//使用反射也行
let m =Reflect.ownKeys(obj); 
console.log(m)

set

//集合:表示无重复值的有序列表
let set=new Set(); 
console.log(set):

Map

//MaP类型是键值对的有序列表,键和值是任意类型
letmap=newMapO; map.setO;
console.log(map);

数组的拓展方法

// 数组的方法from() of()
//from()将伪数组转换成真正的数组
//es5转换
let arr = [].slice.call(arguments); 
console.log(arr)
//es6转换
letarr=Array.from(arguments)
//扩展运算符将伪数组转换成真正的数组 
console.log([...lis]);
//from()还可以接受第二个参数,用来对每个元素进行处理 
Array.from(lis,ele=>ele.textContent);

//2.of()将一组值,转换成数组
console.log(Array.from(3,11,20,'30'));


//4.find()findIndex()
//find()找出第一个符合条件的数组成员
let num = [1, 2, -10, -20, 9, 2].find(n => n < 0) 
console.log(num);
//findIndex()找出第一个符合条件的数组成员的索引



//entries()keys()values()返回一个遍历器可以使用for...of循环进行遍历

//6.incLudes)返回一个布尔值,表示某个数组是否包含给定的值 
console.log([1,2,3]includes(2);

Iterator

是一种新的遍历机制

创建新的达代器

constite=items.[Symbol.iterator]();
console.log(ite.next);//value:"one",done:falsedone如果为f
console.log(ite.nextO); console.log(ite.nextO); console.log(ite.nextO);

生成器

generator函数可以通过yield关键字,将函数挂起,为了改变执行流提供了可能,同时为了做异步编程提供了方案 它普通函数的区别:

  • function后面函数名之前有个*
  • 只能在函数内部使用yield表达式:让函数挂起

异步操作变同步,控制执行顺序

Class

es5造类
function Person(name,age){
	this.name=name;
	this.age = age;
}
Person.prototype.sayName= function(){
	return this.name;
}
let p1=newPerson(小马哥',28); 
console.log(p1);
class Person{
//实例化的时候会立即被调用 
	constructor(name,age){
		this.name = name; 
		this.age = age;
	}
	sayName() {
		return this.name;
	}
	sayAge(){
		return this.age;
	}
}
let p1 = new Person('小马哥',28); 
console.log(pi);

通过object.assign()方法一次性向类中添加多个方法

Object.assign(Person.prototype,{
	sayName(){
		returnthis.name}
	sayAge(){
		return this.age
})

类的继承

classDog extends Animal{
	constructor(name,age,color){
		super(name,age);
		//等价于Animal.call(this,name,age);
	}
}

Promise

Promise是ES6引入的异步编程的新解决方案语法上Promise是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果。

1)Promise构造函数:Promise(excutor){} 2)Promise.prototype.then方法 3)Promise.prototype.catch方法

js
//实例化Promise对象
let res = new Promise(function (resolve, reject) {
    setTimeout(function () {
        console.log('success');
        //调用resolve,对象状态就是成功
        // resolve({name:'zhangSan'});
        //调用reject,对象状态就是失败
        reject({msg:'数据读取失败'});
    },2000)
})
console.log('创建Promise对象之后')
res.then(function (value) {
    //成功调用then回调
    console.log('success', value);
}, function (reason) {
    //失败调用第二个回调
    console.log('error', reason);
})
console.log("创建回调后")

输出:

创建Promise对象之后
创建回调后
success
error { msg: '数据读取失败' }

所以还是异步的

const r = res.then(function (value) {
    //成功调用then回调
    console.log('success', value);
}, function (reason) {
    //失败调用第二个回调
    console.log('error', reason);
})
console.log(r)

res.then的返回结果是Promise对象,内部存储了Promise状态,以及数据

这里的返回值是:

创建Promise对象之后
Promise { <pending> }
创建回调后

等待状态的:

image-20250325211823309

在这里,then里面的回调还可以返回一个Promise对象,这样还可以解决回调地狱

js
//实例化Promise对象
let res = new Promise(function (resolve, reject) {
    setTimeout(function () {
        console.log('异步完成');
        //调用resolve,对象状态就是成功
        resolve({name:'zhangSan'});
        //调用reject,对象状态就是失败
        // reject({msg:'数据读取失败'});
    },500)
})
console.log('创建Promise对象之后')


const r = res.then(function (value) {
    //成功调用then回调
    console.log('success', value);
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
            console.log('第二层异步任务')
            resolve({name:'liSi'});
        })
    });
}, function (reason) {
    //失败调用第二个回调
    console.log('error', reason);
    return reason;
})
console.log(r)
r.then(function () {
    console.log('第二层回调成功')
})
console.log("创建回调后")

还有一个语法糖.catch,就是接收错误的回调函数

js
res.then(function (value) {
    //成功调用then回调
    console.log('success', value);
}).catch(function (err) {
    console.log('error', err);
})

异步

4.1.asyncawait asyncawait两种语法结合可以让异步代码像同步代码一样

  • async函数

    1. async函数的返回值为promise对象,

    2. promise对象的结果由async函数执行的返回值决定 2.

  • await表达式

    1. await必须写在async函数中
    2. await右侧的表达式一般为promise对象
    3. await返回的是promise成功的值
    4. awaitpromise失败了,就会抛出异常,需要通过try...catch捕获处理
async function f1(){
    return 12
}
async function f2(){
    return new Promise((resolve)=>{
        resolve(true)
    })
}

console.log(f2())

await


async function f1(){
    return new Promise((resolve,reject)=>{
        setTimeout(()=>{
            console.log('f1')
            resolve(0)
        },5000)

    })
}
async function f2(){
    let result = await f1();
    console.log(result)
    return new Promise((resolve)=>{
        setTimeout(()=>{
            resolve(true)
            console.log('f2')
        },1000)

    })
}

console.log(f2())

实际上await就是纯纯语法糖,对上述改装:

function f2() {
  return f1().then(function (result) {
    console.log(result);
    return new Promise((resolve) => {
      setTimeout(() => {
        resolve(true);
        console.log('f2');
      }, 1000);
    });
  });
}

一、async 函数的本质

  1. 自动返回 Promise‌ 任何 async 函数‌默认返回一个 Promise‌,无论你是否显式返回 Promise:

    async function foo() { return 1; }
    // 等价于
    function foo() { return Promise.resolve(1); }
  2. 错误处理自动化‌ 在 async 函数中,throw 错误会被自动转换为 ‌rejected Promise‌:

    async function bar() { throw new Error('Oops'); }
    // 等价于
    function bar() { return Promise.reject(new Error('Oops')); }

二、await 的底层机制

await 关键字的作用是 ‌暂停函数执行,等待 Promise 完成‌,其底层实现依赖于 Promise 的 .then() 链式调用:

原始代码(使用 async/await):

javascriptCopy Codeasync function example() {
  try {
    const a = await getDataA();
    const b = await getDataB(a);
    return b;
  } catch (err) {
    console.error(err);
  }
}

脱糖后的等价代码(纯 Promise):

javascriptCopy Codefunction example() {
  return getDataA()
    .then(a => getDataB(a))
    .then(b => b)
    .catch(err => console.error(err));
}

ES6模块化

es6模块功能主要有两个命令构成:exportimport

export用于规定模块的对外接口

import用于输入其它模块提供的功能

一个模块就是一个独立的文件

<scripttype='module'>
//CommonJs和AMD
//Es6module
import {name} from'./modules/index.js/'
<script>

导出模块

export const name='张三' 
export const age=18;
export function sayName(){
	return 'my name is 小马哥';
}
export {sayName}//这样也能导出,必须导出是对象形式

111

export{
	name,age,sayName
}
constobj={
	foo:'foo'
}
export default obj;//export default只能使用一次,export可以使用多次

接收export default

import obj,{name} from'./modules/index.js/'
obj即是默认导出

导出全部

import * from'./modules/index.js/'
//起别名
import * as f from'./modules/index.js/'

MDN介绍使用过程

import defaultExport from "module-name";
import * as name from "module-name";
import { export1 } from "module-name";
import { export1 as alias1 } from "module-name";
import { default as alias } from "module-name";
import { export1, export2 } from "module-name";
import { export1, export2 as alias2, /* … */ } from "module-name";
import { "string name" as alias } from "module-name";
import defaultExport, { export1, /* … */ } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name";

导出

// 导出声明
export let name1, name2/*, … */; // also var
export const name1 = 1, name2 = 2/*, … */; // also var, let
export function functionName() { /* … */ }
export class ClassName { /* … */ }
export function* generatorFunctionName() { /* … */ }
export const { name1, name2: bar } = o;
export const [ name1, name2 ] = array;

// 导出列表
export { name1, /* …, */ nameN };
export { variable1 as name1, variable2 as name2, /* …, */ nameN };
export { variable1 as "string name" };
export { name1 as default /*, … */ };

// 默认导出
export default expression;
export default function functionName() { /* … */ }
export default class ClassName { /* … */ }
export default function* generatorFunctionName() { /* … */ }
export default function () { /* … */ }
export default class { /* … */ }
export default function* () { /* … */ }

// 导出模块合集
export * from "module-name";
export * as name1 from "module-name";
export { name1, /* …, */ nameN } from "module-name";
export { import1 as name1, import2 as name2, /* …, */ nameN } from "module-name";
export { default, /* …, */ } from "module-name";
export { default as name1 } from "module-name";

评论

评论加载中……