ES6变量与解构:let、const与模板字符串全解析

目录

[1. es6的变量和模板字符串](#1. es6的变量和模板字符串)

[1.1 let 和var的差别](#1.1 let 和var的差别)

[1.2 const和var的差异](#1.2 const和var的差异)

[1.3 模板字符串](#1.3 模板字符串)

[2. 解构表达式](#2. 解构表达式)

[3. es6的箭头函数](#3. es6的箭头函数)

[3.1 箭头函数实践](#3.1 箭头函数实践)

[3.2 rest和spread](#3.2 rest和spread)

[3.3 对象创建的语法糖](#3.3 对象创建的语法糖)

[3.4 深拷贝和浅拷贝](#3.4 深拷贝和浅拷贝)

[3.4.1 浅拷贝](#3.4.1 浅拷贝)

[3.4.2 深拷贝](#3.4.2 深拷贝)

[4. ES6模块化的暴露和导入方式](#4. ES6模块化的暴露和导入方式)

ES6中无论以何种方式导出,导出的都是一个对象,导出的内容都可以理解为是向这个对象中添加属性或者方法;

[4.1 分别导出](#4.1 分别导出)

[4.1.1 module.js](#4.1.1 module.js)

[4.1.2 app.js](#4.1.2 app.js)

[4.2 统一导出](#4.2 统一导出)

[4.2.1 module.js](#4.2.1 module.js)

[4.2.2 app.js](#4.2.2 app.js)

[4.3 默认导出](#4.3 默认导出)

[4.3.1 module.js](#4.3.1 module.js)

[4.3.2 app.js](#4.3.2 app.js)


1. es6的变量和模板字符串

1.1 let 和var的差别

  1. let 不能重复声明

  2. let有块级作用域,非函数的花括号遇见let会有块级作用域,也就是只能在花括号里面访问。

  3. let不会预解析进行变量提升

  4. let 定义的全局变量不会作为window的属性

  5. let在es6中推荐优先使用

html 复制代码
<script>
    //1. let只有在当前代码块有效代码块. 代码块、函数、全局
    {
      let a = 1
      var b = 2
    }   
    console.log(a);  // a is not defined   花括号外面无法访问
    console.log(b);  // 可以正常输出

    //2. 不能重复声明
    let name = '天真'
    let name = '无邪'

    //3. 不存在变量提升(先声明,在使用)
    console.log(test) //可以     但是值为undefined
    var test = 'test'
    console.log(test1) //不可以  let命令改变了语法行为,它所声明的变量一定要在声明后使用,否则报错。
    let test1 = 'test1' 


    //4、不会成为window的属性   
    var a = 100
    console.log(window.a) //100
    let b = 200
    console.log(window.b) //undefined

    //5. 循环中推荐使用
    for (let i = 0; i < 10; i++) {
      // ...
    }
    console.log(i);
</script>

1.2 const和var的差异

  1. 新增const和let类似,只是const定义的变量不能修改

  2. 并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。

html 复制代码
<script>
    //声明场景语法,建议变量名大写区分
    const PI = 3.1415926;

    //1.常量声明必须有初始化值
    //const A ; //报错

    //2.常量值不可以改动
    //const A  = 'atguigu'
    //A  = 'xx' //不可改动

    //3.和let一样,块儿作用域
    {
        const A = 'atguigu'
        console.log(A);
    }
    //console.log(A);

    //4.对应数组和对象元素修改,不算常量修改,修改值,不修改地址
    const TEAM = ['刘德华','张学友','郭富城'];
    TEAM.push('黎明');
    TEAM=[] // 报错
    console.log(TEAM)
</script>

1.3 模板字符串

模板字符串(template string)是增强版的字符串,用反引号(`)标识

  1. 字符串中可以出现换行符

  2. 可以使用 ${xxx} 形式输出变量和拼接变量

html 复制代码
<script>
    // 1 多行普通字符串
    let ulStr =
        '<ul>'+
        '<li>JAVA</li>'+
        '<li>html</li>'+
        '<li>VUE</li>'+
        '</ul>'
    console.log(ulStr)    
    // 2 多行模板字符串
    let ulStr2 = `
        <ul>
        	<li>JAVA</li>
        	<li>html</li>
        	<li>VUE</li>
        </ul>`
    console.log(ulStr2)        
    // 3  普通字符串拼接
    let name ='张小明'
    let infoStr =name+'被评为本年级优秀学员'  
    console.log(infoStr)


    // 4  模板字符串拼接
    let infoStr2 =`${name}被评为本年级优秀学员`
    console.log(infoStr2)
</script>

2. 解构表达式

html 复制代码
<script>
    let arr = [11, 22, 33, 44, 55]
    // 使用解构表达式取出数据中的元素
    let [a, b, c, d, e = 10] = arr

    // 当arr只有四个数字时,输出e为默认值10
    console.log(a, b, c, d, e);

    let person = {
        name: "zhangsan",
        age: 10
    }
    // 使用解构表达式获取对象的属性值
    let { age, name } = person
    console.log(name, age);


    // 解构表达式应用在方法的参数列表
    function showArr([a, b, c = 10]) {
        console.log(a, b, c);
    }

    let arr1 = [12, 22]
    showArr(arr1)           // 12 22 undefined(默认值定义可以为10)

</script>

3. es6的箭头函数

html 复制代码
<script>

    //ES6 允许使用"箭头"(=>)定义函数。
    //1. 函数声明
    let fn1 = function(){}
    let fn2 = ()=>{} //箭头函数,此处不需要书写function关键字
    let fn3 = x =>{} //单参数可以省略(),多参数无参数不可以!
    let fn4 = x => console.log(x) //只有一行方法体可以省略{};
    let fun5 = x => x + 1 //当函数体只有一句返回值时,可以省略花括号和 return 语句
    //2. 使用特点 箭头函数this关键字
    // 在 JavaScript 中,this 关键字通常用来引用函数所在的对象,
    // 或者在函数本身作为构造函数时,来引用新对象的实例。
    // 但是在箭头函数中,this 的含义与常规函数定义中的含义不同,
    // 并且是由箭头函数定义时的上下文来决定的,而不是由函数调用时的上下文来决定的。
    // 箭头函数没有自己的this,this指向的是外层上下文环境的this
    
    let person ={
        name:"张三",
        showName:function (){
            console.log(this) //  这里的this是person
            console.log(this.name)
        },
        viewName: () =>{
            console.log(this) //  这里的this是window
            console.log(this.name)	// window没有name属性,所以输出是空
        }
    }
    person.showName()
    person.viewName()
 
    //this应用
    function Counter() {
        this.count = 0;
        setInterval(() => {
            // 这里的 this 是上一层作用域中的 this,即 Counter实例化对象
            this.count++;
            console.log(this.count);
        }, 1000);
    }
    let counter = new Counter();

</script>

3.1 箭头函数实践

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        #xdd{
            display: inline-block;
            width: 200px;
            height: 200px;
            background-color: red;
        }
    </style>
</head>
<body>
    <div id="xdd"></div>
    <script>
       let xdd = document.getElementById("xdd");
       // 方案1 
       xdd.onclick = function(){
            console.log(this)
            let _this= this;  //this 是xdd
            //开启定时器
            setTimeout(function(){
                console.log(this)    // this是window对象
                //变粉色
                _this.style.backgroundColor = 'pink';
            },2000);
        }
        // 方案2
        xdd.onclick = function(){
            console.log(this)
            //开启定时器
            setTimeout(()=>{
                console.log(this)// 使用setTimeout() 方法所在环境时的this对象  xdd
                //变粉色
                this.style.backgroundColor = 'pink';
            },2000);
        }
    </script>
</body>
</html>

3.2 rest和spread

html 复制代码
<script>
    // 1 参数列表中多个普通参数  普通函数和箭头函数中都支持
    let fun1 = function (a, b, c, d = 10) {
        console.log(a, b, c, d)     // 1 2 3 10
    }
    let fun2 = (a, b, c, d = 10) => {
        console.log(a, b, c, d)     // 1 2 3 4
    }
    fun1(1, 2, 3)
    fun2(1, 2, 3, 4)

    // 2 ...作为参数列表,称之为rest参数 解决剩余的参数接收问题
    // 普通函数和箭头函数中都支持,
    // 因为箭头函数中无法使用arguments,rest是一种解决方案
    let fun3 = function (...args) {
        console.log(args)       // Array(3) 0:1  1:2  2:3
    }
    let fun4 = (...args) => {
        console.log(args)       // Array(4)
    }
    fun3(1, 2, 3)
    fun4(1, 2, 3, 4)

    // rest参数在一个参数列表中的最后一个只,这也就无形之中要求一个参数列表中只能有一个rest参数
    //let fun5 =  (...args,...args2) =>{} // 这里报错
</script>

spread是展开,rest在实参上的使用

html 复制代码
<script>
    let arr =[1,2,3]
    // let arrSpread = ...arr;// 这样不可以,...arr必须在调用方法时作为实参使用
    let fun1 =(a,b,c) =>{
        console.log(a,b,c)
    }
    // 调用方法时,对arr进行转换 转换为1,2,3 
    fun1(...arr)

    //应用场景1 合并数组  简单合并,不去重
    let arr2=[4,5,6]
    let arr3=[...arr,...arr2]
    console.log(arr3)

    //应用场景2 合并对象属性  属性名相同会覆盖
    let p1={name:"张三"}
    let p2={age:10}
    let p3={gender:"boy"}
    let person ={...p1,...p2,...p3}
    console.log(person)
</script>

3.3 对象创建的语法糖

html 复制代码
<script>
    class Person {
        // 属性
        // 私有属性,要使这个私有化实现,下面的get和set方法中属性都得是 #n
        // 否则会自行创建新属性
        #n;
        age;
        get name() {
            return this.n;
        }
        set name(n) {
            this.n = n;
        }
        // 实例方法
        eat(food) {
            console.log(this.age + "岁的" + this.n + "用筷子吃" + food)
        }
        // 静态方法
        static sum(a, b) {
            return a + b;
        }
        // 构造器
        constructor(name, age) {
            this.n = name;
            this.age = age;

        }
    }
    let person = new Person("张三", 10);	// 调用构造器
    console.log(person)
    // 访问对象属性
    // 调用对象方法
    console.log(person.name)
    console.log(person.n)

    person.name = "小明"		// 调用set name(n)方法
    console.log(person.age)

    person.eat("火锅")
    console.log(Person.sum(1, 2))

    class Student extends Person {
        grade;
        score;
        study() {
            console.log(`${this.age}岁的${this.name}正在努力学习,考试获得了${this.score}分`);
        }
        constructor(name, age, score) {
            super(name, age);
            this.score = score
        }
    }

    let stu = new Student("学生小李", 18, 100);
    stu.eat("面条")
    stu.study()
</script>

3.4 深拷贝和浅拷贝

3.4.1 浅拷贝

html 复制代码
<script>
    let arr  =['java','c','python']
    let person ={
        name:'张三',
        language:arr
    }
    // 浅拷贝,person2和person指向相同的内存
    let person2 = person;
    person2.name="小黑"
    console.log(person.name)
</script>

3.4.2 深拷贝

html 复制代码
<script>
    let arr  =['java','c','python']
    let person ={
        name:'张三',
        language:arr
    }
    // 深拷贝,通过JSON和字符串的转换形成一个新的对象
    // 先转化给json字符串,再将字符串解析为一个新对象
    let person2 = JSON.parse(JSON.stringify(person))
    person2.name="小黑"
    console.log(person.name)
    console.log(person2.name) 


    // 使用解构表达式也可以实现深拷贝
    let person2 = {... person}
    let arr2 = [...arr]
</script>

4. ES6模块化的暴露和导入方式

ES6中无论以何种方式导出,导出的都是一个对象,导出的内容都可以理解为是向这个对象中添加属性或者方法;

html 复制代码
<!-- 导入JS文件 添加type='module' 属性,否则不支持ES6的模块化 -->
<script src="./app.js" type="module" /> 

4.1 分别导出

4.1.1 module.js

javascript 复制代码
//1.分别暴露
// 模块想对外导出,添加export关键字即可!
// 导出一个变量
export const PI = 3.14
// 导出一个函数
export function sum(a, b) {
  return a + b;
}
// 导出一个类
export class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  sayHello() {
    console.log(`Hello, my name is ${this.name}, I'm ${this.age} years old.`);
  }
}

4.1.2 app.js

javascript 复制代码
/* 
    *代表module.js中的所有成员
    m1代表所有成员所属的对象
*/
import * as m1 from './module.js'

// 使用暴露的属性
console.log(m1.PI)

// 调用暴露的方法
let result =m1.sum(10,20)
console.log(result)

// 使用暴露的Person类
let person =new m1.Person('张三',10)
person.sayHello()

4.2 统一导出

4.2.1 module.js

javascript 复制代码
// 2.统一暴露
// 模块想对外导出,export统一暴露想暴露的内容!
// 定义一个常量
const PI = 3.14
// 定义一个函数
function sum(a, b) {
  return a + b;
}
// 定义一个类
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  sayHello() {
    console.log(`Hello, my name is ${this.name}, I'm ${this.age} years old.`);
  }
}
// 统一对外导出(暴露)
export {
	PI,
    sum,
    Person
}

4.2.2 app.js

javascript 复制代码
/* 
    {}中导入要使用的来自于module.js中的成员
    {}中导入的名称要和module.js中导出的一致,也可以在此处起别名
    {}中如果定义了别名,那么在当前模块中就只能使用别名
    {}中导入成员的顺序可以不是暴露的顺序
    一个模块中可以同时有多个import
    多个import可以导入多个不同的模块,也可以是同一个模块
*/
//import {PI ,Person ,sum }  from './module.js'
//import {PI as pi,Person as People,sum as add}  from './module.js'
import {PI, Person, sum, PI as pi, Person as People, sum as add}  from './module.js'

// 使用暴露的属性
console.log(PI)
console.log(pi)

// 调用暴露的方法
let result1 =sum(10,20)
console.log(result1)
let result2 =add(10,20)
console.log(result2)

// 使用暴露的Person类
let person1 =new Person('张三',10)
person1.sayHello()
let person2 =new People('李四',11)
person2.sayHello()

4.3 默认导出

4.3.1 module.js

javascript 复制代码
// 默认和混合暴露
/* 
    默认暴露语法  export default sum
    默认暴露相当于是在暴露的对象中增加了一个名字为default的属性/方法
    三种暴露方式可以在一个module中混合使用
*/
export const PI = 3.14
// 导出一个函数
function sum(a, b) {
  return a + b;
}
// 导出一个类
class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  sayHello() {
    console.log(`Hello, my name is ${this.name}, I'm ${this.age} years old.`);
  }
}

// 导出默认
// 默认导出在一个js中只能有1个
export default sum

// 统一导出
export {
   Person
}

4.3.2 app.js

default和其他导入写法混用

javascript 复制代码
/* 
    *代表module.js中的所有成员
    m1代表所有成员所属的对象
*/
import * as m1 from './module.js'
import {default as add} from './module.js' // 用的少
import add2 from './module.js' // 等效于 import {default as add2} from './module.js'

// 调用暴露的方法
let result = m1.default(10,20)
console.log(result)
let result2 = add(10,20)
console.log(result2)
let result3 = add2(10,20)
console.log(result3)

// 引入其他方式暴露的内容
import {PI,Person} from './module.js'

// 使用暴露的Person类
let person = new Person('张三',10)
person.sayHello()

// 使用暴露的属性
console.log(PI)
相关推荐
汪子熙40 分钟前
Vite 极速时代的构建范式
前端·javascript
叶常落40 分钟前
[react] js容易混淆的两种导出方式2025-08-22
javascript
摸着石头过河的石头3 小时前
大模型时代的前端开发新趋势
前端·javascript·ai编程
洋流3 小时前
0基础进大厂,第22天 : CSS中的定位布局,你的.container还找不到位置吗?
前端·javascript·面试
讨厌吃蛋黄酥3 小时前
面试官问 “React Hooks 为啥不能在条件里用”,这么答才显真水平!多数人只知其然
前端·javascript·面试
言兴3 小时前
从输入 URL 到页面显示:深入理解浏览器缓存机制
前端·javascript·面试
讨厌吃蛋黄酥3 小时前
前端跨域难题终结者:从JSONP到CORS,一文搞定所有跨域问题!
前端·javascript·后端
阿星做前端3 小时前
coze源码解读:项目启动
前端·javascript
言兴3 小时前
面试题之解析“类组件”与“组件”的本质
前端·javascript·面试
aidingni8883 小时前
告别 DDL 难题:使用 Skapi 的零设置关系数据库 API
前端·javascript