开头

这是根据李炎恢老师的视频,把es6走了一遍,这是我根据他的讲义整理成md格式的文档,同时贴有代码运行结果图,以及对他的文档整理成合理的目录方便快速找到相关的知识点,有需要的收藏,第二部分我到时候会贴在这里。

李炎恢ECMAScript6 / ES6+(二)

01. ECMAScript6 简介和历史

学习要点:
1.ES6 简介
2.ECMAScript 历史
3.学习和创建 Demo
本节课我们来开始了解 ECMAScript6(简称 ES6),着重了解它的标准和历史。

一.ES6 简介

1.ECMAScript6 简称 ES6,是 JavaScript 语言的下一代标准;

2.ES6 的目标是为了实现更加复杂的应用,成为企业级的开发语言;

3.ECMAScript 属于标准制定,而 JavaScript 属于语法实现;

4.ES6 于 2015 年 6 月发布,正式名称为 ECMAScript2015;

5.也就是说 ES6 是 ECMAScript 的一个版本,但却没有 6.x 的说法;

6. ES2016(ES7)、ES2017(ES8)、ES2018(ES9)、ES2019(ES10)版本路线;

7.初学者可能会蒙圈,到底学哪个版本?这个问题,根本不重要~;

8.因为它和软件版本不同,需要各大浏览器兼容性保持一致和兼容,超花时间;

9.我们可以通过这个链接查看 ES6 兼容性情况,并且还有 ES5 和 ES2016+:

http://kangax.github.io/compat-table/es6/

10.经过五年多的发展兼容,ES6 大部分标准得以稳定,或者说 ES6 只是一个泛指;

11.泛指下一代的标准,可以理解为涵盖 ES2015、ES2016、ES2017、ES2018 等;

12. 即使快到 2020 年,很多 JS 工具为了更好兼容,有 ES6 转换 ES5 的选项;

二.ECMAScript 历史

这里,我们给出一张表格,了解一下 ES6 及之前的一些版本情况:

版本 说明
ES1.0 1997 年发布
ES2.0 1998 年 6 月份发布
ES3.0 1999 年 12 月份发布
ES4.0 2000 年没发布的了(废弃了)
ES4.0 2007 年 10 月草案发布(预计次年 8 月发布正式版)
ES3.1 2008 年 7 月发布(吵架把 ES4.0 吵成 3.1 了)
ES5.0 2009 年 12 月发布(3.1 改成了 5.0)
ES5.1 2011 年 6 月份发布
ES6 2013 年 3 月草案冻结
ES6 2013 年 12 月草案发布

三.学习和创建 Demo

1.课程适合有 JavaScript 基础的同学,比如学过之前 ES5 版本的 149 课时的 JS;

2.我们这里重点讨论 ES6 或 ES6+的知识,不会讲解 JavaScript 基础;

3.至于基于 ES6+的 JavaScript 基础课程,后面会分阶段,重新录制,时间不定;

4.为了后面代码课程的便利,我们把 ES6 的项目搭建好;

5.在 C 盘创建 ES6 目录,搭建 01 目录,写入标准的 HTML5 和 JS 文件,测试运行;

02. let 和 const 声明

学习要点:
1.let 声明
2.const 声明
本节课我们来开始学习 ES6 中的 let 和 const 两种声明方式。

一.let 声明

1.ES6 新增了一个新的变量声明:let,它和 var 变量声明非常的类似;

2.首先创建一个块级区域,分别使用 let 和 var 声明一个变量;

//块级区域
{var value = 10;
let count = 20;
}
console.log(value); //10
console.log(count); //引用错误

3.上述例子直观表现为:1.var 出了块级区域有效;2.let 出了块级区域无效

4.var 声明具有变量提升能力,不管在哪里声明,均视为作用域顶部声明;

5.let 声明不具备变量提升能力,离开区块的作用域后,则变量立刻失效;

6.那么,哪种更好?let 更适合局部变量,非常容易掌控且不会导致凌乱;

7.变量提升能力还带来一个区别,就是声明之前使用时,产生的结果不同;

console.log(value);//undefined
var value; //变量提升导致逻辑怪异

8.上面例子对比中,var 在后面声明,前面输出的值从逻辑上较为怪异;

按道理来说,var value; 应该在console.log前面然后正常输出undefined才对。

再来看看count

console.log(count);
let count;

我们发现这个就对了,符合正常的思维逻辑。

那我们放到前面再看呢?

let count;
console.log(count); //undefined

9.在一个区块内部,只要使用 let 声明,这个区域就形成了封闭的作用域;

10.如果在 let 声明前使用变量,这段区域被称为“临时死区(或暂时性死区)”;

if (true) {//死区开始
value = 20;
console.log(value);
//死区结束
let value = 10;
console.log(value);
}

11.“临时死区”简称:TDZ,这段区域使用 typeof 也会报错

console.log(typeof value);
let value;

12.一般情况下,typeof 来判断未声明的变量,只会输出 undefined;

13.var 声明可以重复声明同一个变量,后面会取代前一个变量

var value = 10;
var value = 20;
console.log(value);

14.let 声明不可以重复声明一个变量,会直接报错,就算其中一个是 var

let value = 10;
let value = 20;
console.log(value);var value = 10;
let value = 20;
console.log(value);let value = 10;
var value = 20;
console.log(value);

15.当然,如果一个在作用域外部,一个在作用域内部,则可以并存

let value = 20;
{let value = 10; //不建议相同,会乱的
}
console.log(value);//20

16.在循环中,var 和 let 的区别尤为明显,let 只在循环内部有效;

for (var i = 0; i < 10; i++) {console.log(i);
}
console.log(i); //var 声明,则 10;let 声明,报错

for (let i = 0; i < 10; i++) {console.log(i);
}
console.log(i); //var 声明,则 10;let 声明,报错

17. 如果在循环体内设置函数方法,体外输出 var 会得到不想要的值

var list = [];
for (var i = 0; i < 10; i++) { //把这里改成 let,则会得到想要的值
list[i] = function () {console.log(i);
}
}
list[5](); //这里不管设置多少,结果都是 10

var list = [];
for (let i = 0; i < 10; i++) { //把这里改成 let,则会得到想要的值list[i] = function () {console.log(i);}
}list[5](); //5

二.const 声明

1. const 声明的作用是:创建一个只读的常量,一旦声明不可改变;

2.和 let 声明一样,const 声明的常量无法提升,也存在临时死区;

3.和 let 不同的是,const 声明后必须立刻赋值,否则会报错;

const PI = 3.14;
console.log(PI); //常量约定俗成大写

03. 块级作用域

学习要点:
1.全局作用域
2.块级作用域
本节课我们来开始学习全局作用域和块级作用域的问题。

一.全局作用域

1.如果是 window 对象的内置属性,则输出默认值,而非内置则是undefined;

console.log(window.name);//因为name是window的一个属性,打印结果是一个空字符串
console.log(window.abcd);//它不是window的自带属性,所以打印结果是undefined

2.浏览器环境有一个顶层对象 window,其属性和 var 的全局变量等价;

console.log(window.name);
console.log(window.abcd);console.log(name);//如果直接使用则还是空字符串
console.log(abcd);//这里直接使用,它既不是windown对象的属性,也没有声明,则报错

console.log(window.name === name);//得到结果他们是等价的

再看一个例子,我们此时声名一个非window对象的变量。再看看

var abcd = 10;
console.log(abcd);
console.log(window.abcd);


因此更加印证了标题的结论,简单来说,var声明的全局变量 它就是 window 的属性。

3.var 如果设置了 window 对象的内置属性作为变量,则会直接覆盖;

var name = 'es6';
console.log(name);
console.log(window.name);//被覆盖,所以这里造成了污染

4.结论

1.从上面的例子可以看出,对比现在模块化编程的理念,显得格格不入;
2. 从 WebStorm 环境中根本无法识别 window,因为它是 Node 环境,不支持对象;
3.而 Node 环境的顶层对象 global,只不过其它环境均不支持,不深入展开;

二.块级作用域

1. ES6 之前只有全局作用域和函数作用域,并没有所谓的块级作用域,

2.上一节课的循环体和条件体就是块级作用域,也就是两个花括号区域:{}

3.如果在块级区域不使用 let,就会造成全局变量污染的问题

4.{{{…}}}块级作用域支持多层嵌套,每一层均为封闭的,只作用于此

{{{{{let value = 10;}
console.log(value); //报错
}}}}

5.在 ES6 之前,采用自我立即执行匿名函数的方式来防止变量污染

(function () {var value = 10;
}());
console.log(value); //报错//下面这个就把上面给代替了,方便了很多
{let value = 10;
}

6.ES6 之前函数必须在顶层声明,但违反并不报错,而 ES6 则开始支持

7.只不过块级作用域内的函数声明,还是可以在全局可访问,并没有封闭

{function fn() {console.log('块级函数');
}
}
fn(); //正常访问


此时我想做一个只能在块级内部才能访问到的函数,怎么做?

{let fn = function (){console.log('块级函数')}
}fn();

此时就找不到了,变成了一个私有函数,它只能在块级作用域内部使用
let 结合 函数表达式

{let fn = function (){console.log('块级函数')}fn();
}

04. 数组和对象的解构

学习要点:
1.数组解构
2.对象解构
本节课我们来开始学习 ES6 中数组和对象解构赋值的方法。

一.数组解构

1.ES6 提供了对数组和对象的字面量提取相关数据的方法:解构操作

2.为何要使用解构操作?是因为 JSON 格式的普及,导致大量数据提取工作

3.而这种提取过程,在 ES6 的解构语法中,带来了极大的便捷性

4.数组解构赋值,有两种基本的写法:1.分行解构;2 单行解构;

1.分行解构

let info = ['Mr.Lee', 100, '男']; //数组赋值
let [name, age, gender] = info; //数组解构赋值
console.log(name);
console.log(age);
console.log(gender);

2.如果作为一个变量来申明的话,可以省略一个 let

let info = ['Mr.Lee', 100, '男'],[name, age, gender] = info; //数组解构赋值
console.log(name);
console.log(age);
console.log(gender);

3.单行解构

这里连变量都省掉了。

let [name, age, gender] = ['Mr.Lee', 100, '男'];
console.log(name);
console.log(age);
console.log(gender);

5.从上面的例子分行或单行,都可以确定必须一一完美匹配才可以正确赋值

let [name, age, gender] = ['Mr.Lee', [100, '男']];
console.log(name);
console.log(age);
console.log(gender);


数组层次也需要匹配,才能获取到正确的值

// let [name, age, gender] = ['Mr.Lee', [100, '男']];
let [name, [age, gender]] = ['Mr.Lee', [100, '男']];
console.log(name);
console.log(age);
console.log(gender);

6.如果我只需要其中一个值,不需要的变量使用占位符来填充即可

let [, , gender] = ['Mr.Lee', 100, '男'];console.log(gender);

7.在变量解构时,可以在数组的元素中设置一个默认值

let [name, age, gender = '男'] = ['Mr.Lee', 100];
console.log(name);
console.log(age);
console.log(gender);

8.还有一种…var 的语法,可以将没有赋值的内容都赋值给这个变量

let [name, ...other] = ['Mr.Lee', 100, '男'];
console.log(name);
console.log(other);

二.对象解构

1.对象的解构方式和数组大同小异,定义一个对象字面量,然后解构赋值

//定义对象字面量
let obj = {name : 'Mr.Lee',age : 100,
};
//解构对象字变量
let {name, age} = obj; //或({name, age} = obj);
console.log(name,age);

2.如果说,解构的变量名是已经存在的变量,那会导致覆盖

let obj = {name : 'Mr.Lee',
age : 100,
}, name = 'Mr.Wang'; //被替代
({name, age} = obj);
console.log(name);

3.对象变量解构也可以设置一个默认值,在没有赋值时输出默认值

let obj = {name : 'Mr.Lee',age : 100,
};
//解构对象字变量
let {name, age,gender='男'} = obj; //或({name, age} = obj);
console.log(name,age,gender);

4.如果不想要对象属性名作为解构变量,可以通过键值对的方式更改变量名

let obj = {name: 'Mr.Lee',age: 100,
};//解构对象字变量
let {name:Myname, age:Myage, gender = '男'} = obj;// console.log(name); //失效
// console.log(age);//失效
console.log(Myname);
console.log(Myage);

5.在对象字面量里,还嵌套了对象,解构时也用相同的方法是解开即可

let obj = {name : 'Mr.Lee',age : 100,info : {id : 1,gender : '男'}
};
let {info : {id, gender}} = obj;
console.log(info )//此时info失效
console.log(id)
console.log(gender)

6.对象的解构也支持单行的简写模式

let {name, age} = {name : 'Mr.Lee', age : 100};
console.log(name)
console.log(age)

05.常用的解构

学习要点:
1.其它解构
本节课我们来开始学习 ES6 中更多类型的解构和常用方法;

一.其它解构

1.ES6 除了提供对象和数组解构外,还提供了很多适用的解构方案

2.如果你想要让个普通变量的值进行交换,不必需要第三个变量参与

let key = 1;
let value = '2';console.log(key);
console.log(value);//解构操作,变量互换
[key, value] = [value, key];console.log(key);
console.log(value);

3.如果函数的返回值是一个数组或对象,直接将函数进行赋值解构

function fn() {return ['Mr.Lee', 100, '男'];
}
let [name, age, gender] = fn();console.log(name,age,gender);function fn2() {return {name : 'Mr.Lee',age : 100,gender : '男'}
}
let {name:name2, age:age2, gender:gender2} = fn2();
console.log(name2,age2,gender2);

4.当函数进行参数传递的时候,可以进行数组和对象字面量方式的传参

function fn([name, age, gender]) {console.log(name);console.log(age);console.log(gender);
}
fn(['Mr.Lee', 100, '男']);function fn2({name, age , gender}) {console.log(name);console.log(age);console.log(gender);
}fn2({name : 'Mr.Lee',age : 100,gender : '男'
});

5.除了对象和数组可以使用解构,字符串类型的数据也可以解构

let [x, y, z] = 'ABC';
console.log(x); //A//还可以直接解构出字符串的属性
let {length:len} = 'ABC';
console.log(len); //2

6.还有一些常用的结合需要结合后续内容,之后会展开说明

后面会说明

06.函数的参数

学习要点:
1.参数默认值
2.name 属性
本节课我们来开始学习 ES6 中函数传参默认值等问题;

一.参数默认值

1.ES6 之前函数是无法给参数设置默认值的,而 ES6 支持了这个特性

function fn(name,age = 100,arr = [],obj = {},callback = function () {}) {//参数 1 是必须传递;//其余参数有默认值,可选传递;console.log(arr);console.log(obj);console.log(callback('hello'));
}fn('Mr.Lee', 200, [1,2,3], {key : 1}, function (info) {return info+'-es6';
});

2.函数参数的默认值,也可以是另一个函数的返回值

function pi() {return 3.14;
}
function fn(r, p = pi()) { //pi()返回值交给 pconsole.log(r * r * p);
}
fn(10);

3.如果只想传递第二往后的参数,参数一保持默认值,可用 undefined 占位

function fn(name = 'Mr.Lee', age) { //null,空都不行console.log(name);console.log(age);
}
fn(undefined, 100);

4.支持参数二使用参数一的值作为默认值,反之不可以

function fn(x, y = x) { //(y = x, x)错误console.log(y);
}fn(2);

5.解构变量有不定元素,那么函数的参数也可以有不定参数;

function fn(name, ...other) { //不定参数之后不可再有参数console.log(other);
}
fn('Mr.lee', 100, '男');

二.name 属性

1.ES6 提供了一个 name 属性用于获取函数名,以方便开发者

function fn() {}
let fn2 = function () {};
let obj = {fn3 : function () {}
};
console.log(fn.name);
console.log(fn2.name);
console.log(obj.fn3.name);
console.log((new Function()).name); //匿名函数 anonymous

07.箭头函数和 this

学习要点:
1.箭头函数
2.绑定 this
本节课我们来开始学习 ES6 新增的箭头函数,然后理解一下箭头 this;

一.箭头函数

1.ES6 新增了一个使用(=>)箭头符号定义函数的语法特性,先来个最简单的

let fn = name => name;
console.log(fn('Mr.Lee'));
//翻译成函数代码为:
// let fn = function (name) {//     return name;
// };

2.箭头函数也可以传递两个或以上的参数,并实现运算后返回

let fn = (x, y) => x + y;
console.log(fn(10, 20));
//翻译成函数代码为:
// let fn = function (x, y) {//     return x + y;
// }

3.如果你定义的函数,并不需要传递参数,可以用()括号方式直接返回

let fn = () => 'Mr.Lee';
console.log(fn());
//翻译成函数代码为:
// let fn = function () {//     return 'Mr.Lee';
// };

4.如果函数体需要更复杂的操作,可以将箭头符号右边使用传统函数体

let fn = (x, y) => {return x + y;
};
console.log(fn(10, 20));

5.如果箭头符号右边是对象,返回的是对象,则需要用圆括号包含着

let fn = name => ({name : name, age : 100});
console.log(fn('Mr.Lee').name);
//翻译成函数代码为:
// let fn = function (name) {//     return {//         name : name,
//         age : 100
//     }
// };

6.如果箭头符号左边是对象作为参数,右边是对象的属性运算,也支持

let fn = ({name, age}) => name + ', ' + age;
console.log(fn({name : 'Mr.Lee', age : 100}));

7.自我立即执行函数,也可以使用箭头符号来创建,具体如下

((name) => {console.log(name);
})('Mr.Lee');
//翻译成函数代码为:
// (function (name) {//     console.log(name);
// })('Mr.Lee');

二.绑定 this

1.ES6 之前有一个比较头疼的问题,就是 this 指向的问题,比如下面例子

let obj = {name : 'Mr.Lee',age : 100,fn : function () {console.log(this)setTimeout(function () {console.log(this);console.log(this.name + ', ' + this.age);}, 500)}
};
obj.fn();

2.上面的例子比较典型,this 全局指向 window,在某个对象内部指向当前对象

3.当 obj 对象下包含了类似 setTimeout 函数内部,这时 this 指向就出现问题了

4.Web 环境下,它指向了 Window,而 node 环境下它指向 setTimeout

5.所以,我们通俗的做法,就是将 this 在 setTimeout 外部进行赋值保存;

let obj = {name : 'Mr.Lee',age : 100,fn : function () {// console.log(this)let that = this;setTimeout(function () {// console.log(this);// console.log(this.name + ', ' + this.age);console.log(that.name);}, 500)}
};
obj.fn();

node环境下

浏览器环境

6.箭头函数的出现,彻底解决了 this 在内部指向的问题,直接指向我们所需要

7.因为,箭头函数中的 this 是最外层定义的函数绑定,不受内部影响

let obj = {name : 'Mr.Lee',age : 100,fn : function () {let that = this;setTimeout(() => {console.log(this.name + ', ' + this.age);}, 500)}
};
obj.fn();

08.箭头扩展和尾调用

学习要点:
1.箭头扩展
2.尾调用优化
本节课我们来开始学习箭头一些别的用法,以及尾调用优化的方法。

一.箭头扩展

1.箭头也支持一些内置函数的使用,比如 sort()排序

// let arr = [3, 1, 2].sort(function (a, b) {//     return a - b;
// });
// console.log(arr);//es6
let arr = [3, 1, 2].sort((a, b) => a - b);
console.log(arr);

2.箭头函数不支持 arguments 绑定,请直接使用…other 模式(rest 运算符)

let fn = (x, y) => {return arguments[0] + arguments[1]
}console.log(fn(10, 20));let fn2 = (...other) => {return other[0] + other[1]
};
console.log(fn2(10, 20));

3.箭头函数和普通函数一样,都可以被 typeof 和 instanceof

let fn = (...other) => {return arguments[0] + arguments[1]
}
console.log(typeof fn);//function
console.log(fn instanceof Function);//true

二.尾调用优化

1.什么是尾调用?即在一个函数的最后可执行的一步调用了其它函数

function go(x) {return x + 20;
}let fn = function (x) {//xxx 假设此处有很多代码
return go(x);//在函数内部最后一步调用了go函数
};
console.log(fn(10));

2.那?什么又是尾调用优化?为何要优化?因为:每次尾调用都会创建栈帧;

3.如果尾调次数过多,而内存中的调用栈越来越大,可能就会出现程序问题;

4.尤其是在递归函数的问题上,尾调用优化适合在这种场景中使用;

function fn(x) {if (x <= 1) {return 1;
}
return fn(x - 1);
}
console.log(fn(10));

5.首先要说明,尾调用优化必须是在 ES6 的严格模式下,‘use strict’;

只需要开启严格模式就可以尾调用优化了

'use strict';
function fn(x) {if (x <= 1) {return 1;
}
return fn(x - 1);
}
console.log(fn(10));

6.严格模式,可以设置为全局作用域,也可以在函数体内有效;

这里有个例子,什么叫做严格模式? 它就是规范你的代码的

开启严格模式,智能编辑器它就会报错

'use strict';
let public = 5;
console.log(public);

7.严格模式对变量、对象和函数做了一些代码规范等等,具体规范可以搜索;

8.而对于尾调用,必须严格按照三个规则,才能执行严格模式下的优化,如下:

(1) .尾调用必须 return 返回; // go(x); 错误
(2) .尾调用 return 返回不得含其它操作 // return go(x) + 1; 错误
(3) .尾调用 return 返回的不是函数,而是函数赋值的变量,不在尾部;

09.字符串的扩展改进

学习要点:
1.新增方法
2.模板字符串
本节课我们来开始学习 ES6 新增的字符串方法以及模板字符串功能

一.新增方法

1.对于一些超过两个字符(四字节)的字体,ES6 新增了 codePointAt()方法

// let text = '												

李炎恢ECMAScript6 / ES6+(一)相关推荐

  1. 李炎恢ECMAScript6 / ES6+(二)

    16.Set 数据集合 学习要点: 1.Set 数据集合 本节课我们来开始学习 ES6 新增的 Set 数据集合的用法: 一.Set 数据集合 1.ES6 之前只有数组一种数据结构,而现在提供了 Se ...

  2. 李炎恢-在线商城第三季总结

    1)      首先分析一下表结构 (数据库设计尤为重要) ①   管理员表mall_manage ②   管理员等级表mall_level 解释:level为外键,为管理员等级(一对一) ③   用 ...

  3. 李炎恢 js教程 拖拽上 思路解析

    李炎恢再讲js教程 拖拽上 讲到一个登录框,通过鼠标移动登录框到浏览器各个地方,我们现在对李炎恢的怎么想出进行分析: 问题期望是什么? 1.我们通过鼠标点击登录框,然后登录框被移动,松开鼠标,停止移动 ...

  4. java 李炎恢_李炎恢 jquery 66讲视频教程PDF文件完整版全集

    [实例简介] 李炎恢老师在线教程66讲所用的PDF笔记课件,共16章.使用本文档可以省去记笔记的过程. 分享给大家,希望对大家有用. [实例截图] [核心代码] faae1ed4-23fe-4919- ...

  5. easyui java1234_李炎恢jQuery EasyUI视频教程 下载

    李炎恢jQuery EasyUI视频教程  下载 01.[jQuery EasyUI]第1章 jQuery EasyUI入门 02.[jQuery EasyUI]第2章 使用EasyUI 03.[jQ ...

  6. 李炎恢Bootstrap视频教程下载

    李炎恢Bootstrap视频教程下载 课程目录:     01.[Bootstrap] 第1章 Bootstrap介绍.avi     02.[Bootstrap] 第2章 排版样式.avi     ...

  7. 李炎恢老师XHTML视频教程DIV+CSS教程与课件代码

    [No32]李炎恢老师XHTML视频教程DIV+CSS教程与课件代码 课程目录: css专题 0.视频项目源代码+素材 第1章 XHTML学前准备(1课时) 第2章 HTML基本结构(2课时) 第3章 ...

  8. 李炎恢bootstrap写首页内容上思路解析

    关于利用bootstrap做一张图片对应一段文字,这是李炎恢思路是一生二,二生三,三生万物的思路 第一步 做一个大盒子,这好比修房子,你要划出一块区域给我 <div class="ro ...

  9. 北风网 李炎恢老师全部视频教程下载地址大全

    (1)啥都不说了[北风网 李炎恢老师]视频教程大全百度网盘下载地址: http://pan.baidu.com/share/home?uk=4278436023#category/type=0 李炎恢 ...

最新文章

  1. dumpbin发现没有入口函数_详解VS2019 dumpbin查看DLL的导出函数
  2. python有道自动翻译_Python 调用有道翻译接口实现翻译
  3. python解析并读取PDF文件:函数总结
  4. 线程并发库和线程池的作用_线程和并发介绍
  5. java导出pdf 含图片_java 生成PDF含图片和中文件实现代码
  6. 2021-2025年中国船用炉灶行业市场供需与战略研究报告
  7. 数据新闻的四大发展特点
  8. 注册ActiveX控件时DllRegisterServer调用失败的解决方法
  9. html手机表白弹窗,抖音弹窗表白代码怎么玩 弹窗表白制作方法与教程一览
  10. 解决java:找不到符号办法
  11. 区分苹果开发者的网址(开发者网址和管理您的appid网址)及证书信息
  12. Centos中IP地址的动静转换
  13. docker的安装和部署
  14. 3D游戏的碰撞检测是如何实现的?
  15. 基于51单片机十字路口交通灯_5s黄灯闪烁
  16. 政务OA办公系统搭建现状
  17. java编程题库公众号,已获万赞
  18. Atlas——数据治理工具的使用
  19. 扶我起来,前端还没倒下,我不能睡
  20. 有选择读取word表格中的数据并写入excel文件中

热门文章

  1. 一加7t人脸识别_600美元起售:一加7T真机抢先看 90Hz屏/环形3摄
  2. 一加7t人脸识别_90Hz新品,一加7T系列国内发布日期官宣
  3. HBase :HBase高级shell管理命令
  4. HTML中input输入框动态模糊匹配
  5. python图像识别依赖包安装和环境配置
  6. 为啥一定要用残差图检查你的回归分析?
  7. ubuntu18.04系统安装+基本环境配置【原创】
  8. 【转】dB、dBm是什么意思~
  9. 无线传感网学习笔记(8)—— DSDV路由协议 和 AODV路由协议
  10. mysqlclient安装失败解决方案