前端工程化---ES6

发布于:2025-02-27 ⋅ 阅读:(11) ⋅ 点赞:(0)

前端工程化简介 

什么是前端工程化

前端工程化`是使用`软件工程的方法``单独`解决`前端`的开发流程中`模块化、组件化、规范化、自动化`的问题,其主要目的为了提高效率和降低成本。

app中的前端相关的代码剥离出来,形成一个独立的工程使用相关的专门的技术来实现前端代码四化称为前端代码工程化

 前端工程化实现技术栈

 前端工程化实现的技术栈有很多,我们采用ES6+nodejs+npm+Vite+VUE3+router+pinia+axios+Element-plus组合来实现

前后端分离模式特点:

1 开发分离

2 部署分离

ES6_变量和模板字符串

let`和`const`,用来声明变量

 let 和var的差别

    1、let 不能重复声明

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

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

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

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

 const和var的差异

const就是不可修改的letfinal修饰的变量      

    1、新增const和let类似,只是const定义的变量不能修改(const声明一个变量必须给其一个值,只声明不赋值不行,先声明后赋值也不行)

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

 模板字符串(template string)

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

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

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

例如:

let city="北京"

     let str=` <ul>

        <li></li>

        <li>${city}</li>

        <li></li>

        <li></li>

        <li></li>

    </ul>`

ES6_解构表达式与箭头函数

解构表达式

数组解构赋值

+ 可以通过数组解构将数组中的值赋值给变量

例如

       let arr=[11,22,33,44]

       let [a,b,c,d,e=10]=arr//对应索引赋值,e没有对应的值则是其默认值10;如果没有设置默认值则是undefined

对象解构赋值

+ 可以通过对象解构将对象中的值赋值给变量,

例如

       let person={

        name:"zhangsan",

        age:10

       }

       let {name,age}=person//变量名要与对应的属性名一致

       console.log(name)//打印zhangsan

       console.log(age)//打印10

函数参数解构赋值

+ 解构赋值也可以用于函数参数。

例如:

       let arr=[11,22,33,44]

       function showArr([a,b,c]){

        console.log(a,b,c)

       }

       showArr(arr)

es6的箭头函数

> ES6 允许使用“箭头” 义函数。语法类似Java中的Lambda表达式

    1箭头函数声明

        let fun1=function(){}//普通函数声明

        let fun2 = (x) =>{ return x+1 }//箭头函数声明  与Java中的Lambda类似

        let fun3 = x =>{return x+1}//参数列表中有且只有一个参数,()可以省略不写

        let fun4 = x => console.log(x)//方法体中只有一行代码 {} 可以省略不写

        let fun5 = x => x+1 //方法体中,有且只有一行代码,且这行代码return返回结果的代码,那{}与return都可以省略

    2. 使用特点 箭头函数this关键字

     在 JavaScript 中,this 关键字通常用来引用函数所在的对象,或者在函数本身作为构造函数时,来引用新对象的实例。

     但是在箭头函数中,this 的含义与常规函数定义中的含义不同,并且是由箭头函数定义时的上下文来决定的,而不是由函数调用时的上下文来决定的。

        箭头函数没有自己的this

        箭头函数中的this是外层上下环境中的this

可变参数:rest和spread

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        //rest剩余的,解决剩余的参数接收问题
        // let fun1=(a,b,c,d,...arr)=>{
        //     console.log(a,b,c,d)
        //     console.log(arr)
        // }
        // fun1(1,2,3,4,5,6,7,8,9)
        //spread 展开  rest在实参上的使用
        let arr=[1,2,3]
   //  let info=...arr //意思是let info=1,2,3 这样赋值是错误的,...arr必须在调用方法时,作为实参使用
   let fun2=(a,b,c)=>{
    console.log(a,b,c)
   }
   fun2(arr)//意思是将arr这个数组赋值给a这一个变量,b,c,并没有赋值
   fun2(...arr)//意思是将arr的数组元素依次赋值给变量
   //快速合并数组
   let a=[1,2,3]
   let b=[4,5,6]
   let c=[7,8,9]
   let d=[...a,...b,...c]
   //快速合并对象
   let person1={name:"Jack"}
   let person2={age:"15"}
   let person3={gender:"boy"}
   let persons={...person1,...person2,...person3}
   console.log(persons)
    </script>
</head>
<body>
</body>
</html>

类和对象的语法糖

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        class Person{
            name;
            a;
            //私有属性
            #gender;
            get name(){
              return  this.name
            }
            set name(name){
                this.name=name
            }
            get age(){
                return this.a
            }
            set age(a){
                this.a=a
            }
            get gender(){
                return this.#gender
            }
            set gender(gender){
                this.#gender=gender
            }
            //实例方法
            eat(food){
                console.log(`${this.a}岁的${this.name}正在吃${food}`)
            }
            //静态方法
            static sum(a,b){
                return a+b
            }
            //构造器
            constructor(name,age,gender){
                this.name=name
                this.a=age
                this.#gender=gender
            }
        }
        let person=new Person()
        /*
        属性赋值时:
        当属性名与方法名一样时赋值优先使用属性赋值
        当属性名与方法名不一样时,此时属性的赋值调用对应相同方法名的set方法
        调用属性时同理
        */
        person.name="zhangsan"//当属性名与方法名一样时赋值优先使用属性赋值
        person.age=14//当属性名与方法名不一样时,此时属性的赋值调用对应相同方法名的set方法
        console.log(person)
        //实例方法
        person.eat("火锅")
        //静态方法
        console.log(Person.sum(10,20))
        //构造器与私有属性访问
        let person2=new Person("xiaoming",16,"girl")
        console.log(person2.gender)

        //extends类
        class Student extends Person{
            score;
            id;
            study(){
                console.log(`${this.a}岁的${this.name}正在努力学习,考试获得了${this.score}`)      
            }
            constructor(name,age,gender,score,id){
                super(name,age,gender)
                this.score=score
                this.id=id
               
            }
        }
        let stu=new Student("wangwu",19,"boy",90,1)
        stu.study()

    </script> 
</head>
<body>
    
</body>
</html>

ES6深拷贝与浅拷贝

        浅拷贝:仅拷贝了变量指向的引用地址,并没有产生一份新的数据

        深拷贝:拷贝的变量的改变对于原变量没有任何影响

        方式一:利用解构表达式完成

        方式二:对于对象的深拷贝还可以利用JSON转换

     //浅拷贝

       let arr=[1,2,3,4]

       let arr2=arr//实际是将arr的引用地址给arr2,也就是说arr与arr2指向同一个地址

       let person1={name:"zhnagsan"}

       let person2=person1

       console.log(person2)

       //深拷贝----------------解构表达式

       let arr3=[9,8,7,6]

       let arr4=[...arr3]

    //    let person3={name:"lisi"}

    //    let person4={...person3}

       //对于对象的深拷贝还可以利用JSON转换

       let person3={name:"lisi"}

       let person4=JSON.parse(JSON.stringify(person3))

模块化处理

> 模块化是一种组织和管理前端代码的方式,将代码拆分成小的模块单元,使得代码更易于维护、扩展和复用。包括了定义、导出、导入以及管理模块的方法和规范。前端模块化的主要优势如下:

1.  提高代码可维护性:通过将代码拆分为小的模块单元,使得代码结构更为清晰,可读性更高,便于开发者阅读和维护。

2.  提高代码可复用性:通过将重复使用的代码变成可复用的模块,减少代码重复率,降低开发成本。

3.  提高代码可扩展性:通过模块化来实现代码的松耦合,便于更改和替换模块,从而方便地扩展功能。

+ ES6模块化的几种暴露和导入方式

    1. 分别导出

    2. 统一导出

    3. 默认导出

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

1 分别导出与导入

    分别导入:每一个成员都要用export修饰,才能对外暴露

      *代表module.js的所有成员、

      无论何种方式导入,导入的内容都会被当成一个对象处理

      使用一个对象来接收所有的成员

      格式 import * as 对象名 from '要导入的文件地址'-----------------------统一格式

      注意:

           因为会把导出内容当作对象处理,所以一定要有一个对象名

           写地址时如果使用相对路径 "./"不能省略

           要到入的文件中的内容只有被export修饰才能被使用(export代表向外暴露的)

           html文件导入文件时使用script<>,其中src属性用来写地址(写地址时如果使用相对路径 "./"不能省略)

           同时要指明类型type为module

导出

//变量
export const PI=3.14
const PI2=3.14
//方法
export function sum(a,b){
    return a+b
}
//类
export class Person{
    name;
    age;
    constructor(name,age){
        this.name=name;
        this.age=age;
    }
    sayHello(){
        console.log(`hello,my name is ${this.name},I'am ${this.age}years old`)
    }
}

导入

import * as m1 from './module.js'
console.log(m1.PI)
let person=new m1.Person("zhangsan",10)
person.sayHello()

 统一导出与导入

导出

将export统一写在最后,将要暴露的成员用 { } 括起来

//变量
 const PI=3.14
const PI2=3.14
//方法
 function sum(a,b){
    return a+b
}
//类
 class Person{
    name;
    age;
    constructor(name,age){
        this.name=name;
        this.age=age;
    }
    sayHello(){
        console.log(`hello,my name is ${this.name},I'am ${this.age}years old`)
    }
}
export {PI,sum,Person}

导出-----------------使用解构表达式

//统一导出情况下:使用解构表达式的方式导入
import {PI,sum,Person} from './module.js'
//解构表达式里可以起别名了({PI as pi,sum,Person})起别名后就只能用别名
console.log(m1.PI)
let person=new m1.Person("zhangsan",10)
person.sayHello()

3 默认导出与导入

导出

默认导出再js中只能有一个

例如:export default sum

导入

import add from './module.js'

console.log(add(10,40))