ES6 ~ ES11新特性


变量声明

let: 块级作用域(即花括号范围内)丶不存在变量提升丶不允许重复声明丶不影响作用域链

const: 块级作用域丶常量(不能改变变量引用,引用对象内部可修改)丶需赋初值丶一般用大写

解构赋值

允许按照一定模式从数组和对象中提取值,对变量进行赋值

1.数组
    const ARRAY = ['Tom','Jerry']
    let [cat,mouse] = ARRAY;//解构赋值
    console.log(cat); //Tom
    console.log(mouse); //Jerry
2.对象
    const cat = {
        name: 'Tom',
        skill(){
            console.log('catch the mouse')
        }
    }
    let {name,skill} = cat;//解构赋值
    console.log(name);//Tom
    skill();//catch the mouse

模板字符串

新的声明字符串的方式反引号:``

    //可以直接出现换行符
    let str = `Tom
               Jerry`;
    //变量拼接
    let name = 'Tom'
    let concat = `${name} and Jerry`;
    console.log(concat) //Tom and Jerry

对象简化写法

1. 在大括号里面直接写入变量和函数
    let name = 'Tom'
    let from = function(){
        console.log('Tom and jerry')
    }
    //在大括号里面直接写入变量和函数
    const info = {
        name,
        from,
        simple(){ //简化写法
            console.log('eq from')
        }
    }

箭头函数

  • 箭头函数,this始终指向函数声明所在作用域下的this的值
  • 不能作为构造函数实例化对象
  • 不能使用arguments变量
    let fn = function(a,b){
        console.log(a+b);
        console.log(this.name); //Jerry
    }
    //箭头函数,this始终指向函数声明所在作用域下的this的值
    let fns = (a,b) =>{
        console.log(a+b);
        console.log(this.name) //Tom
    }
    window.name = 'Tom';
    let mouse = {
        name: "Jerry"
    }
    fn.call(mouse,1,2);
    fns.call(mouse,3,4);
    //不能作为构造函数实例化对象
    let Cat = (name) => {
        this.name =name;
    }
    let Tom = new Cat('Tom'); //报错,无法实例化对象
    //不能使用arguments变量
    let fn = () => {
        console.log(arguments);//报错
    }
    fn();

函数参数默认值

可以与解构赋值结合

    //函数形参设置默认值
    let add = (a,b = 10) => {
        return a + b;
    }
    console.log(add(1,2)); //3
    console.log(add(1)) //11
    //使用解构赋值传参
    function info({name,type}){
        console.log(name); //Tom
        console.log(type); //cat
    }
    info({
        name: 'Tom',
        type: 'cat'
    });

rest参数: 即可变参数

    let fn = (...args) => {
        console.log(args[0]); //1
        console.log(args[1]); //2
    }
    fn(1,2)

扩展运算符[…]

可以将数组转换为逗号分隔的参数序列

    const arr = [1,2,3];
    let fn = function(){
        console.log(arguments) //参数等价与fn(1,2,3)
    }
    fn(...arr);
    fn(1,2,3);

    //合并数组
    const arr1 = [1,2,3]
    const arr2 = [4,5,6]
    const arr3 = [...arr1,...arr2] //合并数组
    console.log(arr3) //[1,2,3,4,5,6]
Symbol
    //创建Symbol对象
    let s = Symbol()
    console.log(typeof s);//symbol
    //比较
    let s2 = Symbol('S');
    let s3 = Symbol('S');
    console.log(s2 === s3); //false
    //比较
    let s4 = Symbol.for('S');
    let s5 = Symbol.for('S');
    console.log(s4 === s5) //true

迭代器(Iterator)

具备iterator接口的类型数据(可以用for of遍历)

ES6 默认的 Iterator 接口部署在数据结构的Symbol.iterator属性,即一个数据结构只要具有Symbol.iterator属性,就可以认为是“可遍历的”(iterable)

ArrayArgumentsSetMapStringTypedArrayNodeList

    let arr = [1,2,3,4,5];
    //使用for of遍历
    for(let a of arr)
        console.log(a);//1,2,3,4,5
    //自定义迭代器
    const option = {
        name: 'Cartoon',
        arr:[
            'Tom',
            'Jerry',
            'Nemo',
            'Simba'
        ],
        [Symbol.iterator](){
            let i = 0;
            return {
                next: () => {
                        return {value:this.arr[i++],done:this.arr.length === i - 1}
                }
            }
        }
    }
    for(let s of option){
        console.log(s); //Tom Jerry Nemo Simba
    }

生成器

ES6提供的一种异步编程解决方案,其实就是一个特殊的函数

    //生成器函数异步编程,纯回调的特殊函数,可以分段执行,通过迭代器遍历
    function * it(){
        yield 'a';
        yield 'b';
        yield 'c';
    }
    let iterator = it();
    //可以分段执行
    console.log(iterator.next()) //{value: 'a', done: false}
    console.log(iterator.next()) //{value: 'b', done: false}
    console.log(iterator.next()) //{value: 'c', done: false}

    for(let c of it()){
        console.log(c)  //a //b //c
    }

传参

    function * it(arg){
        console.log(arg); //a
        let one = yield 11;
        console.log(one); //b
        let two = yield 22;
        console.log(two); //c
    }

    let iterator = it('a');
    iterator.next();
    iterator.next('b');
    iterator.next('c');

实现定时器

    function one(){
        setTimeout(() => {
            console.log(1);
            it.next();
        },1000)
    }
    function tow(){
        setTimeout(() => {
            console.log(2);
            it.next();
        },1000)
    }
    function three(){
        setTimeout(() => {
            console.log(3);
            it.next()
        },1000)
    }

    function * gen(){
        yield one();
        yield tow();
        yield three();
    }
    let it = gen();
    it.next(); //1 //2 //3

Promise

使用

    const p = new Promise(function(resolve,reject){
        let data = "success";
        let error = "error";
        setTimeout(function (){
            //resolve(data);//成功返回
            reject(error);//失败返回
        },1000);
    });

    //调用promise的then方法
    p.then(function(value){
        console.log(value); //success
    },function(reason){
        console.log(reason);//error
    })

通过Promise封装AJAX

    //通过Promise封装ajax
    const ajax = ({method,url}) => {
        return new Promise((resolve,reject) => {
            const xhr = new XMLHttpRequest();
            //开启
            xhr.open(method,url);
            //发送
            xhr.send();
            //处理响应
            xhr.onreadystatechange = function(){
                if(xhr.readyState === 4){
                    if(xhr.status >= 200 && xhr.status < 300)
                        resolve(xhr.response)
                    else
                        reject(xhr.status);
                }
            }
        })
    }

    //使用
    ajax({
        method: "GET",
        url: "https://localhost/api/v3/api-docs/bioland"
    }).then(value => {
            console.log(value);
        },
        reason => {
            console.log(reason);
        }
    )

链式调用: Promise的then方法返回值会封装为一个Promise对象

    //链式调用: Promise的then方法会返回一个Promise对象
    const p = new Promise((resolve, reject) => {
        resolve("success");
        //reject("error");
    })

    p.then(value => {
        console.log(value); //success
        return 'v: ' + value;
    },reason => {
        console.log(reason); //error
        return "r: " + reason;
    }).then(value => {
        console.log(value); //v: success;
    },reason => {
        console.log(reason); //r: error
    })

catch方法: 失败的回调: 即reject方法的回调

    //catch方法: 失败的回调: 即reject方法的回调
    let p = new Promise((resolve,reject) => {
        //resolve("success");//成功
        reject("error");//失败
    })

    p.then(value => {
        //成功的回调
        console.log("t: " + value); //t: success
    }).catch(reason => {
        //失败的回调
        console.log("c: " + reason); //c: error
    })

集合

Set : 不重复集合,实现了iterator接口

    /**
        //方法
        size: 返回集合元素的个数
        add: 向集合中添加一个元素
        delete: 删除元素,返回boolean值
        has: 检测集合中是否包含某个元素,返回boolean值
    */
    let set = new Set([3,4,2,3]);
    //实现了iterator可以使用for-of遍历
    for(let s of set) console.log(s) // 3,4,2
    set.add(1);//向集合中添加元素1
    for(let s of set) console.log(s); //3,4,2,1
    console.log(set.has(3));//true
    set.delete(3);//删除集合中的元素3
    for(let s of set) console.log(s) //4,2,1
    console.log(set.has(3));//false
    console.log(set.size)//3
    set.clear();//清空集合
    console.log(set.size)//0

Map : k-v键值对集合,也实现了iterator接口

/**
    //方法
    size: 返回Map的元素个数
    set: 增加一个新元素,返回当前Map
    get: 返回键名对象的值
    has: 检测Map中是否包含某个元素
    clear: 清空集合,返回undefined
*/

    //map集合
    let map = new Map();
    map.set(1,{name:"Tom"})
    map.set("array",[1,2,3])
    map.set("function",() => {console.log("function")})
    for(let e of map) console.log(e)
    //[1, {…}]
    //['array', Array(3)]
    //['function', ƒ]

class 类

class基本

    //class
    //1: ES5方式
    function People(name,gender){
        this.name = name;
        this.gender = gender;
    }
    People.prototype.toString = function(){
        console.log("name:" + this.name + " gender:" + this.gender)
    }
    //实例化对象
    let p = new People("Tom","male")
    p.toString();
    //2: ES6 class方式
    class User{
        constructor(name,gender) {
            this.name = name;
            this.gender = gender;
        }
        toString(){
            console.log("name:" + this.name + " gender:" + this.gender);
        }
    }
    let u = new User("Jerry","male");
    u.toString();

静态成员: 属于函数,不属于实例化对象

    //静态成员: 只属于函数,不属于实例化对象
    class People{
        static name = 'Jerry';
        static toStr(){
            console.log('name: ' + this.name)
        }
    }
    //实例化对象
    let p = new People()
    People.toStr(); //属于函数: name: Jerry
    p.toStr(); //不属于实例化对象: 报错

类继承

    //继承
    class Base{
        constructor(name) {
            this.name = name;
        }
        toStr(){
            console.log("name: " + this.name)
        }
    }
    class BaseImpl extends Base{
        constructor(name,gender) {
            super(name);
            this.gender = gender;
        }
        hello(){
            console.log("Hello");
        }
    }

    let impl = new BaseImpl("Tom","male");
    impl.toStr(); //name: Tom
    impl.hello(); //Hello

重写: 子类声明和父类同名方法

    //重写: 子类声明和父类同名方法
    class Base{
        constructor(name) {
            this.name = name;
        }
        toStr(){
            console.log("name: " + this.name)
        }
    }
    class BaseImpl extends Base{
        constructor(name,gender) {
            super(name);
            this.gender = gender;
        }
        //重写父类方法
        toStr(){
            console.log("name: " + this.name + " gender:" + this.gender)
        }
    }

    let impl = new BaseImpl("Jerry","male");
    impl.toStr(); //name: Jerry gender:male

getter 和 setter方法

    //getter 和 setter方法
    class People{
        get name(){
            return this._name;
        }
        set name(name){
            this._name = name;
        }
        toStr(){
            console.log("name:" + this._name);
        }
    }
    let p = new People();
    p.name = 'Jerry';
    p.toStr(); //name:Jerry
    p.name = 'Tom';
    p.toStr(); //name:Tom

数值扩展

    // Number.EPSILON 是javascript表示的最小精度
    //可用于判断小数相等
    console.log(Number.EPSILON) //2.220446049250313e-16
    function equals(a,b){
        //取差绝对值与最小精度对比
        return (Math.abs(a-b) < Number.EPSILON)
    }
    console.log(0.1 + 0.2 === 0.3) //false
    console.log(equals(0.1+0.2,0.3)) //true

    //二进制: 0b开始, 八进制: 0o开始, 十六进制: 0x开始
    console.log(0b10)//2
    console.log(0o10)//8
    console.log(10)//10
    console.log(0x10)//16

    //Number.isFinite 检测一个数值是否为有限数
    //Infinity : 无限数
    console.log(Number.isFinite(100))//true
    console.log(Number.isFinite(Infinity))//false

    //Number.isNaN 检测一个数值是否为NaN
    console.log(Number.isNaN(123)); //false

    //Number.parseInt , Number.parseFloat 字符串转整数
    console.log(Number.parseInt("10.24ab"));//10
    console.log(Number.parseFloat("10.24ab"));//10.24

    //Number.isInteger 判断一个数是否为整数
    console.log(Number.isInteger(4));// true
    console.log(Number.isInteger(4.4));// false

    //Math.trunc 抹掉小数部分
    console.log(Math.trunc(3.4))//3

    //Math.sign 判断一个数为正=1,负=-1,零=0
    console.log(Math.sign(100))//1
    console.log(Math.sign(-100))//-1
    console.log(Math.sign(0))//0

对象方法扩展

    //Object.is() 判断两个值是否完全相等
    console.log(Object.is(120,120)); //true
    console.log(Object.is(NaN,NaN)); //true;
    console.log(NaN === NaN); //fasle;

    //Object.assign() 对象合并,同属性名会被后面替换,否则就合并
    const master = {
        host: 'localhost',
        port: '3306',
        username: 'root',
        password: 'root',
        charset: 'UTF-8'
    }
    const slave = {
        host: '127.0.0.1',
        port: '1521',
        username: 'admin',
        password: 'admin',
        driver: 'o'
    }
    console.log(Object.assign(slave,master));
    //{host: 'localhost', port: '3306', username: 'root', password: 'root', driver: 'o',charset: "UTF-8"}

    //Object.setProtoTypeOf() 设置原型对象
    //Object.getProtoTypeOf() 获取原型对象
    const school = {
        name: 'school'
    }
    const country = {
        name: 'CN'
    }
    Object.setPrototypeOf(school,country);
    console.log(Object.getPrototypeOf(school).name); //CN

模块化

export 暴露接口,import 导入

1. 分别暴露

1.1 a.js

//export 暴露接口
export let name = 'Tom';
export function hello(){
    console.log("hello")
}

1.2 在其他文件中导入

<script type="module">
    //1.通用导入方式
    import * as a from "/js/a.js"
    console.log(a.name);
    a.hello();

    //2.解构赋值方式导入: 可以用as设置别名
    import {name as n,hello} from "/js/a.js"
    console.log(n)
    hello()
</script>
2. 统一暴露

2.1 b.js

let name = 'Tom';
function hello(){
    console.log('hello');
}

//统一暴露
export {name,hello}

2.2 在其他文件中导入

<script type="module">
    import * as b from "/js/b.js";
    console.log(b.name);
    b.hello()
</script>
3.默认暴露

3.1 c.js

//默认暴露
export default {
    name: 'Tom',
    hello: function(){
        console.log('hello');
    }
}

3.2 在其他文件中导入

<script type="module">
    //1.通用导入方式
    import * as c from "/js/c.js";
    console.log(c.default.name);
    c.default.hello();

    //2.解构赋值方式: 默认暴露导入必须通过as设置别名
    import {default as dc} from "/js/c.js";
    console.log(dc.name);
    dc.hello();

    //3.简便形式: 只针对默认暴露
    import sdc from "/js/c.js";
    console.log(sdc.name);
    sdc.hello();
</script>
4. 浏览器对模块化导入的支持

可以使用一个js文件作为入口文件,在里面导入所需模然后使用,最后在页面引入这个入口文件js

4.1 app.js: 入口js文件,引入所需模块并使用

//入口文件
import * as a from "./a.js";
import * as b from "./b.js";
import * as c from "./c.js";


//使用
console.log(a.name);
console.log(b.name);
console.log(c.default.name);
a.hello();
b.hello();
c.default.hello();

4.2 在页面引入入口文件app.js

//引入
<script src="./js/app.js" type="module"></script>

ES7新特性

Array.prototype.includes和**幂运算
    //数组的includes方法,检测数组是否包含某个元素
    const arr = ['a','b','c']
    console.log(arr.includes('c'))
    console.log(arr.indexOf('c') > 0) //旧版本实现方式

    // ** 幂运算
    console.log(2 ** 10); //1024
    console.log(Math.pow(2,10))//1024  //旧版本实现方式

ES8新特性

1. async 和 await
  • asayc作为一个关键字放到函数前面,这样普通函数就变为了异步函数

  • async函数配合await关键字使用(阻塞代码往下执行)
    是异步方法,但是阻塞式的

  • 同步代码编写方式: Promise使用then函数进行链式调用,一直点点点,是一种从左向右的横向写法;async/await从上到下,顺序执行,就像写同步代码一样,更符合代码编写习惯

  • async/await是对Promise的优化 : async/await是基于Promise的,是进一步的一种优化,不过在写代码时,Promise本身的API出现得很少,很接近同步代码的写法

  • async函数返回值为promise对象

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

  • await必须写在async函数中

  • await右侧的表达式一般为promise对象

  • await返回的是promise成功的值

  • await的promise失败了,就会抛出异常,需要通过try…catch捕获处理

async函数

    //async函数
    async function fn(){
        //返回字符串
        //return 'Tom'; //1.字符串,返回结果为一个成功的promise对象
        //return;   //2.空,返回结果为一个成功的promise对象
        //throw new Error("error"); //3.抛出错误,返回结果为一个失败的promise对象
        return new Promise((resolve,reject) => {
            //resolve("success");
            reject("error");
        }) //4.promise对象,直接返回
    }

    const result = fn();

    result.then(value => console.log(value))
        .catch(reason => console.log(reason))

    //Tom   //1
    //undefined     //2
    //Error: error  //3
    //success //4
    //error   //4

await函数

    const p = new Promise((resolve,reject) =>{
        resolve("success");
    })

    async function fn(){
        let result = await p;
        console.log(result);//替换掉promise的链式调用写法变成顺序调用,更符合编程习惯
    }
    fn()
2. 对象方法扩展
  • Object.keys,Object.valuesObject.entries : 类比java中Map集合的keys,values,和entrySet
  • Object.getOwnPropertyDescriptors: 对象结构属性描述
    const obj = {
        name: 'Tom',
        arr: [1,2,3]
    }
    console.log(Object.keys(obj)) //['name', 'arr']
    console.log(Object.values(obj)) //['Tom', Array(3)]
    console.log(Object.entries(obj))//即[[keys数组],[values数组]]
    console.log(Object.getOwnPropertyDescriptors(obj))

ES9新特性

扩展运算符和rest参数
  • rest参数(...obj)会将多余不配的参数放入obj中

        function fn({name,...obj}){
            console.log(name) //Tom
            console.log(obj) //{num: 1, arr: Array(3), str: 'cat'}
        }
    
        fn({
            name: 'Tom',
            num: 1,
            arr: [1,2,3],
            str: 'cat'
        })
  • 扩展运算符...: 会拆开对象将其属性放入一个对象中取

        const a = {
            name: 'Tom'
        }
        const b = {
            arr: [1,2]
        }
        const c = {
            num: 3
        }
        console.log({...a,...b,...c}) //{name: 'Tom', arr: Array(2), num: 3}
    
正则扩展

命名捕获分组

    let url = '<a href="http://brysong.com">Bryson</a>'
    const reg = /<a href="(.*)">(.*)<\/a>/;
    const result = reg.exec(url);
    console.log(result); //["<a href=\"http://brysong.com\">Bryson</a>","http://brysong.com","Bryson",...]
    console.log(result[1])//http://brysong.com
    console.log(result[2])//Bryson

    //?<名字>  : 分组并设置名称
    let url1 = '<a href="http://brysong.com">Bryson</a>'
    const reg1 = /<a href="(?<u>.*)">(?<n>.*)<\/a>/;
    const result1 = reg1.exec(url1);
    console.log(result1) //[groups: {u: 'http://brysong.com', n: 'Bryson'},...]
    console.log(result1.groups.u)//http://brysong.com
    console.log(result1.groups.n)//Bryson

断言

    //正向断言 ?=
    //反向断言 ?<=
    let str = '123XXX前999后XXX结尾';
    //正向断言
    const reg = /\d+(?=后)/; //匹配 数字+`后`字的形式的数字内容
    console.log(reg.exec(str)[0]) //999

    //反向断言
    const reg1= /(?<=前)\d+/;//匹配`前`+数字形式的数字内容
    console.log(reg1.exec(str)[0])

dotAll模式

  • . 表示匹配任意的单个字符,但是行终止符除外,即以下四个

    • U+000A 换行符(\n

    • U+000D 回车符(\r

    • U+2028 行分隔符(line separator)

    • U+2029 段分隔符(paragraph separator)

  • dotAll模式则表示匹配一切字符,引入新的修饰符s: (dotAll模式),以前有i: (ignore)忽略大小写,g: (global)全局匹配等

    console.log(/mazey.happy/.test('mazey\nhappy')); // false
    console.log(/mazey.happy/s.test('mazey\nhappy')); // true

ES10新特性

  • Object.fromEntries : 可以将二维数组转为对象

  • Object.entries: 将对象转为二维数组ES8

  • 字符串扩展方法

    • trimStart: 清除字符串首部空白
    • trimEnd: 清除字符串尾部空白
  • 数组扩展方法

    • flat : 多维数组降维
    • flatMap: flat和map操作结合,如果map返回结果是多维数组,则降维返回
        //flat
        const arr = [1,2,[3,4]];
        console.log(arr.flat())//[1, 2, 3, 4]
        const arr1 = [1,[2,[3,[4]]]];
        console.log(arr1.flat()) //[1, 2, [3,[4]]]
        console.log(arr1.flat(2))//降维两层: [1, 2, 3, [4]]
        console.log(arr1.flat(3))//降维3层: [1, 2, 3, 4]
    
        //flatMap: 相当于flat+map 操作结合,如果map返回结果是多维数组,则降维返回
        const arr2 = [1,2,3,4];
        console.log(arr2.flatMap(e => e * 10)) //[10, 20, 30, 40]
    
        console.log(arr2.map(e => [e * 10]))//[[10], [20], [30], [40]]
        console.log(arr2.flatMap(e => [e * 10])) //[10, 20, 30, 40]
    
        console.log(arr2.map(e => [[e * 10]]))//[[[10]], [[20]], [[30]], [[40]]]
        console.log(arr2.flatMap(e => [[e * 10]])) //[[10], [20], [30], [40]]
        console.log(arr2.flatMap(e => [[e * 10]]).flatMap(e => e * 10))//[100, 200, 300, 400]
  • Symbol.prototype.description: Symbol对象描述

ES11新特性

  • 私有属性: #属性名

        class Person{
            name;
            #age; //只能在类内部操作
            constructor(name,age) {
                this.name = name;
                this.#age = age;
            }
            info(){
                console.log("name: " + this.name + " age: " + this.#age);
            }
        }
    
        const p = new Person('Tom',10);
        console.log(p.name)//Tom
        //console.log(p.#age)//报错,类外部无法获取私有属性
        p.info() //name: Tom age: 10
  • Promise.allSettled: 方法返回一个在所有给定的 promise 都已经 fulfilledrejected 后的 promise,并带有一个对象数组,对象数组每个对象表示对应的 promise 结果

  • String.prototype.matchAll: 方法返回一个包含所有匹配正则表达式的结果及其分组捕获组的迭代器

  • 可选链操作符?.: 存在的话再去读取后续属性(以前.xxx)如果不存在读取会报错

        function fn(config){
            //常规读取(需要判断对象是否存在,存在才能读取,直接读取会报错)
            const name = config && config.user && config.user.name;
            //使用可选链操作符,存在才会读取,不存在直接返回undefined
            const name1 = config?.user?.name;
            console.log(name);
            console.log(name1);
        }
    
        fn({user: undefined})
        //undefined
        //undefined
        fn({user:{
            name: 'Tom'
            }})
        //Tom
        //Tom
  • 动态import

    • d.js

      function hello(){
          console.log("hello");
      }
      export {hello}
    • 其他文件动态import导入使用

      <script type="module">
          //动态import导入
          import('./js/d.js').then(module => {
              module.hello();//hello
          })
      </script>
  • BigInt: 进行更大数值运算

        //n结尾表示BigInt类型
        let n = 520n;
        console.log(typeof n); //bigint
    
        //普通整数转BigInt
        let v = 12;
        console.log(BigInt(v)) //12n
    
        //更大数值运算
        let max = Number.MAX_SAFE_INTEGER;
        console.log(max++); //9007199254740991
        console.log(max++); //9007199254740992
        console.log(max++); //9007199254740992 错误,无法再计算
        //使用BigInt正常计算
        let big = BigInt(max);
        console.log(big); //9007199254740992n
        console.log(big += BigInt(1)); //9007199254740993n
        console.log(big += BigInt(1)); //9007199254740994n
  • globalThis: 旨在通过定义一个标准的全局属性来整合日益分散的访问全局对象的方法,浏览器中默认指向window对象,

    编写可在多种环境下工作的可移植 JS 代码是很困难的。每个宿主环境都有稍微不同的对象模型。因此,要访问全局对象,需要在不同的 JS 环境中使用不同的语法。

    随着globalThis属性的引入,访问全局对象将变得更加简单,并且不再需要检测代码运行的环境


文章作者: Bryson
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Bryson !
评论
 上一篇
JavaFX-初识 JavaFX-初识
概述 JavaFX是一个基于Java的开源框架,用于Java平台的图形用户界面(GUI)开发技术领域,是Java swing的继承者 JavaFX还可以使用任何支持Java虚拟机(JVM)的脚本语言编写,如Kotlin丶Groovy和Sc
2022-05-28
下一篇 
Spring-Boot:Deploying Spring Spring-Boot:Deploying Spring
概述 部署方式 war包方式构建和部署 jar包方式部署到云平台 将Spring Boot运行在Docker容器(container) 部署方式1. 构建和运行Spring Boot应用常见的有以下几种方式 使用IDE构建和运行(
2020-10-10
  目录