文章目录

  • 一、let和const
  • 二、Symbol
  • 三、模板字符串
    • 3.1 什么是模板字符串
    • 3.2 字符串新方法
  • 四、解构表达式
    • 4.1 数组解构
    • 4.2 对象解构
  • 五、Set()、map()数据结构
    • 5.1 map()是什么及写法?
      • 5.1.1 map()是什么及写法?
      • 5.1.2 map()下的内置方法:
    • 5.2 Set()
      • 5.2.1 Set()是什么及写法?
      • 5.2.2 Set()下的内置方法:
      • 5.2.3 Set去重:
  • 六、ES6新加的数组方法及使用(Array)
    • 6.1 新增数组方法总结
    • 6.2 新增数组方法使用
  • 七、ES6新加的对象方法及使用(Object)
    • 7.1 新增对象方法总结
    • 7.2 对象声明的简写
    • 7.3 …(对象扩展运算符)
  • 八、箭头函数
  • 九、Promise
    • 9.1 Promise是什么
    • 9.2 Promise的特点
    • 9.3 Promise下的方法
    • 9.4 Promise下的静态方法
  • 十 、class(面向对象编程)
  • 十一、模块化开发
    • 11.1 导入
    • 11.2 导出
    • 11.3 模块化优点
    • 11.4 模块化缺点
  • 总结

一、let和const

let:定义变量,只能在块作用域里访问,不能声明同名变量。不存在变量提升的问题
const:定义常量,不能声明同名变量,只能在块作用域里访问,而且不能修改,但是在定义的对象时对象属性值可以改变,不存在变量提升的问题

二、Symbol

用于表示一个独一无二的值,不能与其他数据类型进行运算。它是JavaScript中的第七种数据类型,与undefined、null、Number(数值)、String(字符串)、Boolean(布尔值)、Object(对象)并列,是基本数据类型

//这样创建一个Symbol值
const newValue = Symbol();//或者使用let创建
let newValue = Symbol();
console.log(newValue );  //Symbol()//因为Symbol是基本数据类型,而不是对象所以不能用 new 创建,
//会出现Symbol is not a constructor的报错
const newValue  = new Symbol();

三、模板字符串

3.1 什么是模板字符串

在模板字符串没出现之前,处理字符串:通过“\”和“+”来构建模板,非常的麻烦并且很容易漏写符号,对ES6的模板字符串出现后,用${``}可以直接实现,非常方便;

 let arr = '我是字符串'let html = `<div>文字文字<span>${arr}</span></div>`

3.2 字符串新方法

1、includes():判断字符串是否包含参数字符串,返回boolean值。

let str = 'apple,orange,banana';
str.includes('apple');//true

2、startsWith() / endsWith():判断字符串是否以参数字符串开头或结尾。返回boolean值。这两个方法可以有第二个参数,一个数字,表示开始查找的位置。

let str = 'apple,orange,banana';
str.startsWith('apple');//true
str.endsWith('peach');//false

3、repeat():方法按指定次数返回一个新的字符串

let a='hi'
console.log('hello'.repeat(2));   //'hihi'

4、padStart()/padEnd():用参数字符串按给定长度从前面或后面补全字符串,返回新字符串。

let arr='app'
console.log(arr.padEnd(4,'l'));//appl
console.log(arr.padEnd(6));  //'app '如果没有传入值将用空格代替console.log(arr.padStart(5,'o')); //ooapp

四、解构表达式

4.1 数组解构

ES6允许按照一定模式,从数组或者对象中提取值,对变量进行赋值,这被称为解构。
解构的作用是可以快速取得对象当中的元素或属性,无需再用arr[x]或者obj[key]传统的方式进行赋值

let arr=[1,2,3]
let [a,b,c] =arr
console.log(a,b,c);    //1,2,3let arr=[1,2[3,4]];
let [a,b[c,d]]=arr
console.log(a,b,c,d)//1,2,3,4let arr=[1,2,];
let [a,b,c]=arr
console.log(a,b,c); //1,2,undefined//...是剩余运算符,表示赋值运算符右边除第一个值外剩余的都赋值给b
let arr=[1,2,3]
let [a,..b] = arr;
console.log(a,b);//1,[2,3]

4.2 对象解构

需要注意的点是变量名和属性都可以修改,但是必须相同

let obj = { name: "张三", age: 12, sex: "man"
};let { name, age, sex } = obj;
//或者(想解构哪个变量就把哪个变量写进去)
let { name, age, sex } = { name: "张三", age: 10, sex: "man"
};
//都能打印出以下结果
console.log(name, age, sex); //'张三' 10 'man'//错误写法  name1和name变量名不同,是打印不出来的
let obj = { name1: "张三", age: 10, sex: "man"
};let { name, age, sex } = obj;

五、Set()、map()数据结构

5.1 map()是什么及写法?

5.1.1 map()是什么及写法?

map属于es6新增加的数据结构,map()是键值对,里面的键和值可以任意,Map对象有一个size属性,存储了键值对的个数,而object对象没有类似属性。

let newMap = new Map([['name','zhangsan'],['age',10]]);
console.log(newMap );  //{'name'=>'zhangsan','age'=>10}

5.1.2 map()下的内置方法:

map.set(key,value):设置键名key对应的键值value,返回整个map解构,如果key已经有值,则进行覆盖,可以链式操作

 let newMap = new Map([["name", "zhangsan"],["age", 10],]);newMap.set("sex", "man");console.log(newMap); //{'name' => 'zhangsan', 'age' => 10, 'sex' => 'man'}newMap.set("name", "lisi");console.log(newMap); // {'name' => 'lisi', 'age' => 10, 'sex' => 'man'}newMap.set("sex", "man").set("aaa", "hahah");console.log(newMap); // {'name' => 'lisi', 'age' => 10, 'sex' => 'man', 'aaa' => 'hahah'}

map.get(value):get方法读取key对应的键值,如果找不到就返回underfined

 let newMap = new Map([["name", "zhangsan"],["age", 10],]);console.log(newMap.get("age")); //10console.log(newMap.get("ages")); //undefined

map.has(value):判断该值是否为met成员,返回一个布尔值

let newMap = new Map([["name", "zhangsan"],["age", 10],]);console.log(newMap.has("aaa")); //falseconsole.log(newMap.has("name")); //trueconsole.log(newMap); //{'name' => 'zhangsan', 'age' => 10}

map.clear():清除所有数据,没有返回值

 let newMap = new Map([["name", "zhangsan"],["age", 10],]);newMap.clear();console.log(newMap); // {size: 0}

map.entries():返回键值对的遍历器

 let newMap = new Map([["name", "zhangsan"],["age", 10],]);newMap.entries();console.log(newMap); //{'name' => 'zhangsan', 'age' => 10}

5.2 Set()

5.2.1 Set()是什么及写法?

Set()是值的集合,是类数组,里面的值的唯一的,可以实现数组去重

//注意:必须传数组进去,否则会报错
let newSet = new Set([1,2,3]);
console.log(newSet );  //{1,2,3}

5.2.2 Set()下的内置方法:

Set.add(value):添加一个数据,返回Set解构本身,可以进行链式操作

    let newSet = new Set([1, 2, 3]);newSet.add(4)console.log(newSet)//{1, 2, 3, 4}newSet.add(4).add(5).add(6)console.log(newSet)//{1, 2, 3, 4, 5,6}

Set.delete(value):删除指定数据,返回一个布尔值,表示是否删除成功

let newSet = new Set([1, 2, 3]);
console.log(newSet.delete(3)); //false 表示不包含3这个元素
console.log(newSet.delete(1));//true 表示删除成功
console.log(newSet)//{1,2}

Set.has(value):判断该值是否为Set成员,返回一个布尔值

let newSet = new Set([1, 2, 3]);
console.log(newSet.has(3))//true
console.log(newSet.has(7))//false

Set.clear():清除所有数据,没有返回值

let newSet = new Set([1, 2, 3]);
newSet.clear()
console.log(newSet); // {size: 0}

size:表示Set解构的长度

let newSet = new Set([1, 2, 3]);
console.log(newSet.size)//3

5.2.3 Set去重:

let arr=[1,2,2,2,4,3,6,4];
let data=new Set(arr);
let newArr = Array.from(data);
console.log(newArr);  //[1,2,3,4,6]//或者
let arr=[1,2,2,2,4,3,6,4];
console.log([...new Set(arr)]);  //[1,2,3,4,6]

六、ES6新加的数组方法及使用(Array)

6.1 新增数组方法总结

方法名 参数 返回值 是否影响原数组
map() 函数 数组
filter() 函数 数组
find() 函数 返回符合条件的元素,之后的值不会再调用执行函数。如果没有符合条件的元素返回 undefined
forEach() 函数 undefined 基本数据类型不改变原数组,引用数据类型改变原数组
includes() 数值 true/false
some() 函数 true/false
every() 函数 true/false

6.2 新增数组方法使用

map():原数组的每一项执行函数后,返回一个新数组

    let arr = [10, 20, 30, 40];let arr1 = [];arr.map((val) => {val = val * 2;arr1.push(val);});console.log(arr1); //[20, 40, 60, 80]console.log("原数组", arr); //[10, 20, 30, 40]

filter():过滤数组,返回符合条件的新数组

//过滤出大于10的值let arr = [10, 20, 30, 40]let arr1 = [];arr.filter((val) => {if (val > 10) {arr1 .push(val)}})console.log(arr1 )//[20, 30, 40]console.log("原数组", arr); //[10, 20, 30, 40]

find():查找,返回符合条件的对应的那个值

//查找id=2的值
var memoList = [{id: 1, name: '1'},{id: 2, name: '2'},{id: 3, name: '3'}]
// 用 editItem 变量将 查找出来的数据进行接收
var editItem = memoList.find((ele) => {return ele.id == 2 })  console.log(editItem ) //{id: 2, name: '2'}//但是查找id=10的值就返回underfinedvar editItem = memoList.find((ele) => {return ele.id == 10 })  console.log(editItem )//underfinedconsole.log("原数组", memoList ); //[{id: 1, name: '1'},{id: 2, name: '2'},{id: 3, name: '3'}]

forEach():是循环遍历数组中的每一项,没有返回值

//基本数据类型不改变原数组,引用数据类型改变原数组let arr = [10,20,30,40];let arr1 = [];arr.forEach((v, i) => {v = v * 2;arr1.push(v);});console.log(arr1);//[20, 40, 60, 80]console.log('原数组',arr);//[10, 20, 30, 40]let arr2 = [{ v: 1 }, { v: 2 }, { v: 3 }];let arr3 = [];arr2.forEach((val) => {val.v = val.v * 2;arr3.push(val.v);});console.log(arr3);//[2, 4, 6]console.log('原数组',arr2); //[{ v: 2 }, { v: 4 }, { v: 6 }]

includes():判断数组是否包含一个指定值,包含输出true,不包含输出false

    let arr = [10, 20, 30, 40];let ary = arr.includes(10);console.log(ary);//trueconsole.log("原数组", arr); //[10, 20, 30, 40]

some():对数组中的每一项进行判断,若有其中一个符合条件,返回true,否则返回false

   let arr = [10, 20, 30, 40];let arr1 = arr.some(function (val) {return val > 10;});console.log(arr1); //trueconsole.log("原数组", arr); //[10, 20, 30, 40]

every():对数组中的每一项进行判断,若都符合条件,返回true,否则返回false

   let arr = [10, 20, 30, 40];let arr1 = arr.every(function (val) {return val > 10;});console.log(arr1); //falseconsole.log("原数组", arr); //[10, 20, 30, 40]
方法名 用途
Array.from() 用于将对象转换为数组,类数组转数组
Array.of() 用于将一组值转化为数组

Array.from():用于将对象转换为数组,类数组转数组

 let obj = {0: 'zhangsan',1: '10',2: 'wangwu',length:3}console.log(Array.from(obj))// ['zhangsan', '10', 'wangwu']

Array.of():用于将一组值转化为数组

//Array.of()使用方法:
console.log(Array.of(1,2,3))//[1,2,3]

七、ES6新加的对象方法及使用(Object)

7.1 新增对象方法总结

方法名 作用 返回值
Object.assign() 用于对象的合并,将原对象的所有可枚举属性,复制到目标对象 返回目标对象
Object.keys() 获取所有对象的key属性集合 返回一个数组
Object.values() 获取所有对象的value属性集合 返回一个数组
Object.entries() 返回多个数组 返回多个数组,每个数组是 key–value

Object.assign():用于对象的合并,将原对象的所有可枚举属性,复制到目标对象

    const obj1 = { a: 1, b: 2 };const obj2 = { b: 5, c: 3 };//对象合并,把后面对像合并到第一个对象,对象里相同的属性会覆盖let newobj = Object.assign({}, obj1, obj2);console.log(newobj); // {a: 1, b: 5, c: 3}

Object.keys():获取所有对象的key属性集合

    const obj1 = { a: 1, b: 2, c: 3 };let newobj = Object.keys(obj1);console.log(newobj); //['a', 'b', 'c']

Object.values():获取所有对象的value属性集合

    const obj1 = { a: 1, b: 2, c: 3 };let newobj = Object.values(obj1);console.log(newobj); //[1, 2, 3]

Object.entries():返回多个数组

    const obj1 = { a: 1, b: 2, c: 3 };let newobj = Object.entries(obj1);console.log(newobj); //[['a', 1] ['b', 2] ['c', 3]]

7.2 对象声明的简写

//ES6出现之前的写法let a=10;let obj={a:a,showa:function(){console.log(obj.a)}}//ES6出现之后的写法let a=10;let obj={a,showa:(){console.log(obj.a)}}

7.3 …(对象扩展运算符)

用…表示,功能是吧数组或者类数组对象展开成一系列用逗号隔开的值,可以将类数组转真正的数组,其他功能如下:
数组合并

let arr1=[1,2];
let arr2=[3,4];
console.log([...arr1,...arr2])//[1,2,3,4]

对象合并

let obj1 = { a: 1 };
let obj2 = { b: 2 };
let newObj ={...obj1,...obj2}
console.log(newObj); // { a: 5, b: 2}

求数组的最大值

let arr=[1,2,3,4,5]
console.log(Math.max(...arr))//5

浅拷贝(引用传递)

let arr1 = [1, 2];
let arr2 = [...arr1];
arr2.push(3)
console.log(arr2); //[1,2,3]
console.log('原数组', arr1); //[1,2]
//或者
let obj1 = {name: "zhangsan",age: 10,sex: "man",};let obj2 = { ...obj1 };console.log(person2); //{name: 'zhangsan', age: 10, wife: "man"}

将类数组转真正的数组

//html:
<ul><li>111<li><li>111<li>
<ul>
//jslet aLi = document.querySelectorAll('li');aLi = [...aLi];aLi.push(document.body)console.log(aLi)//[li,li,body]

八、箭头函数

1、箭头函数有更简洁的写法,不用写function
2、箭头函数是匿名函数
3、箭头函数没有prototype属性,不可以把箭头函数当作构造函数,所以不能用new关键字调用箭头函数,否则抛出一个错误、也没有arguments属性
4、箭头函数和普通函数最大的区别在于其内部this永远指向其父级的this
5、箭头函数适用于无复杂逻辑(回调函数)的函数里面,例如可以用在map()、reduce()、filter()、forEach()的回调函数中。
6、不要在最外层使用箭头函数,this会指向window,而且无法改变,最好在外层包裹一层普通函数,把this控制在可见范围内。

ler fn=function(srt)=>{return srt
}
let fn = srt => srt;
//当只有一个参数时,括号可以省略,函数体只有单行return语句时,大括号也可以省略。

箭头函数和普通函数最大的区别在于其内部this永远指向其父级的this

   var fn = () => {alert(this);//[object Window]};fn()

箭头函数适用于无复杂逻辑(回调函数)的函数里面,例如可以用在map()、reduce()、filter()、forEach()的回调函数中。

 let arr = [10,20,30,40];arr.forEach((v) => {console.log(v)});

箭头函数没有arguments属性

  function Fun(a) {//普通函数console.log('普通函数',a)console.log('普通函数',arguments)}let fun = (b) => {//箭头函数console.log('箭头函数',b)console.log('箭头函数',arguments)}Fun(12)fun(11)


箭头函数没有prototype属性,所以不能用new关键字调用箭头函数,会报错(可以复制代码到编辑器好好研究下~)

 //普通函数function Fun(a) {this.a=a// console.log('普通函数', a)}//箭头函数let fun = (b) => {this.b=b// console.log('箭头函数', b)}console.dir(Fun)console.dir(fun)let p1 = new Fun(12)console.log('普通函数', p1)let p2 = new fun(11)console.log('箭头函数', p2)

九、Promise

9.1 Promise是什么

Promise是一种异步编程的解决方案,比传统的回调函数更强大更合理

 let promise = new Promise((resolve, reject) => {resolve("成功状态中的参数");reject("失败状态中的参数");})//这里的then是上面的Promise实例下面的then,这里的then返回值也是一个Promise实例.then((data) => {console.log(data); //成功状态中的参数})//这里的then不是上面的Promise实例下面的then,是前一个then返回的Promise实例.then((data) => {console.log(data); //underfined}).catch((data) => {console.log(data); //失败状态中的参数}).finally(()=>{console.log('无论成功或者失败,都执行'); //失败状态中的参数})

9.2 Promise的特点

1、Promise有三种状态,分别是peding(进行中)、resolve(成功)、rejected(失败),并且状态一旦设定就不会改变
2、Promise是用于解决传统回调函数的回调地狱的问题
3、Promise是函数做参数

9.3 Promise下的方法

1、 then()方法:接收Promise中resolve(成功)传进来的方法和参数,then()方法也返回一个Promise对象,并且then()方法可以链式调用
2、 catch()方法:接收Promise中rejected(失败)传进来的方法和参数
3、 finally()方法:无论是成功状态还是失败状态,都执行finally()中的方法

9.4 Promise下的静态方法

1、 Promise.all()
用于将多个Promise实例,包装成一个新的Promise实例,接受一个数组做参数,只有数组里面的每个状态都变成resolve,则新的Promise实例状态才会变成resolve,输出是一个数组,Promise.all()方法常用于并发请求,比如页面多个不相关的请求接口,使用并发请求可以有效减少页面响应时间,比如批量上传图片,如果有一个图片失败则终止上传等等
再次注意:

  1. 当a1,a2,a3的状态都变为resolve时,a的状态才会变成resolve,此时a1,a2,a3返回值组是一个数组,传递给a中回调函数
  2. 当a1,a2,a3中有一个状态变为rejected时,a的状态就变成rejected,第一个状态变为rejected的返回值就会传递给a中的回调函数
const a1 = new Promise((resolve,reject)=>{});
const a2 = new Promise((resolve,reject)=>{});
const a3 = new Promise((resove,reject)=>{});
const a= Promise.all([p1,p2,p3]);Promise.all([a1,a2]).then(data=>{console.log(data)  // data为一个数组  ['请求成功','上传成功']
}).catch(err=>{console.log(err)
})Promise.all([a1,a2,a3]).then(data=>{console.log(data)
}).catch(err=>{console.log(err) // 失败 打印结果为 'error'
})

2、 Promise.race()
无实际用处,面试会问到

const a1 = new Promise((resolve,reject)=>{});
const a2 = new Promise((resolve,reject)=>{});
const a3 = new Promise((resove,reject)=>{});
const a = Promise.race([a1, a2, a3]);

上面代码中,只要a1、a2、a3之中有一个实例率先改变状态,a的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给a的回调函数

十 、class(面向对象编程)

1、是ES6提供了更接近传统语言高级的写法,引入class(类)这个概念,作为对象的模板,通过class关键字,可以定义类
2、基本上ES6的class可以看作是语法糖,他的绝大部分功能,ES5都能做到,新的class写法只是让对象原型的写法更清晰,更像面向对象的编程写法而已

//class的固定写法
class Person {constyuctor(name,age){this.name=name;this.age=age;}init(){return this.name + this.age}
}

十一、模块化开发

11.1 导入

ES6使用关键字 import 导入模块(文件),有两种常用的方式:

import '模块名称'  from  '路径';
import  '路径';

11.2 导出

ES6 通过 export 和export default 导出模块。

let name = 'ren',age = 10;
export {name,age};//变量需要用大括号

11.3 模块化优点

1、灵活架构,焦点分离
2、方便模块间组合、分解
3、方便单个模块功能调试、升级
4、多人协作互不干扰

11.4 模块化缺点

性能损耗
1、系统分层,调用链会很长
2、模块间发送消息会很耗性能

总结

本文章仅限于本人自己知识点的梳理,如有不正确,欢迎指正

ES6新特性总结-面试必会相关推荐

  1. ES6新特性----面试

    ES6新特性 关键字 let关键字 const关键字 解构赋值 变量的解构赋值 数组的解构赋值 对象的解构赋值 字符串的解构赋值 数值和布尔值的解构赋值 函数参数的解构赋值 用途 模板字符串 箭头函数 ...

  2. 前端开发的ES6新特性(学生党必看)

    一:ES6新特性-let&const 1.常量const const常量(声明之后不允许改变,一旦声明必须初始化, 否则报错) 2.let变量 let声明的变量有严格的作用域 var声明的变量 ...

  3. html5 跳转参数不显示_HTML5、CSS3、ES6新特性总结

    前言:HTML5.CSS3.ES6新特性,可以说是基础前端的面试的必考题了,以下是关于新特性的基本总结. HTML5: 语义化的区块和段落元素:<section>,<article& ...

  4. lsdyna如何设置set中的node_list_如何快速掌握es6+新特性及核心语法?

    国庆刚刚结束,我们开始一波新的学习进程吧. ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了.作为前端必备技能,我们来快速开始吧 接 ...

  5. javascript ES6 新特性之 扩展运算符 三个点 ...

    对于 ES6 新特性中的 ... 可以简单的理解为下面一句话就可以了: 对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中. 作用类似于 Object.assign() ...

  6. ES6新特性(函数默认参数,箭头函数)

    ES6新特性之 函数参数的默认值写法 和 箭头函数. 1.函数参数的默认值 ES5中不能直接为函数的参数指定默认值,只能通过以下的变通方式:   从上面的代码可以看出存在一个问题,当传入的参数为0或者 ...

  7. ES6新特性之了解ES6以及其发展历史

    ES6 新特性 现在使用主流的前端框架中,如ReactJS.Vue.js.angularjs等,都会使用到ES6的新特性,作为一名高级工程师而言,ES6也就成为了必修课,所以本套课程先以ES6的新特性 ...

  8. es6 获取对象的所有值_前端开发必备 - ES6 新特性之 Set和Map数据结构

    往期回顾: 前端开发必备 - ES6 新特性之 let 和 const 命令 前端开发必备 - ES6 新特性之 变量的解构赋值 前端开发必备 - ES6 新特性之 字符串的拓展 前端开发必备 - E ...

  9. 尚硅谷es6新特性笔记

    尚硅谷es6新特性笔记 一.let与const let的变量声明以及声明特性 const的变量声明以及声明特性 const.let.var 三者之间的区别 二.变量解构赋值 三.模板字符串 四.对象的 ...

最新文章

  1. 《算法帝国》——华尔街,第一张多米诺骨牌
  2. 【深度学习】深度学习模型中的信任危机及校正方法
  3. mysql now unixtime_MySQL时间函数from_unixtime()date_format()unix_timestamp()now()使用说明
  4. python +keras实现图像分类(入门级例子讲解)
  5. 【转】Win8/8.1/Win7小技巧:揪出C盘空间占用的真凶
  6. 每天学习点--------第五天(2017-10-9) 摘要: 常用的集合
  7. [linux]centos6.3安装flash插件rpm方式
  8. POI导入数据的过程中,遇到读取以科学计数法显示的数据
  9. vim插件command-t安装
  10. candence测量尺寸
  11. java实战小结-Controller报错:Content type ‘multipart/form-data;boundary=----WebKitFormBoundaryxxxx not supp
  12. 多元线性方程的python解法
  13. Skynet服务器框架系列教程,skynet 服务端框架安装/运行
  14. 由浅入深!大牛耗时一年最佳总结,让你的app体验更丝滑!3面直接拿到offer
  15. 自媒体攻略合集,教你如何做一名能赚钱的自媒体人
  16. 七夕节 看到许多停止更新的blog 莫名有点淡淡的忧桑
  17. html自定义select样式,自定义select样式
  18. 8g内存一般占用多少_电脑8G内存够用吗?
  19. 前端应该知晓的PWA
  20. openwrt自动启动脚本

热门文章

  1. python编程自学_Python编程自学:一小时python入门教程
  2. Word和Excel中的常用办公操作
  3. 计算机usb端口没反应,电脑usb接口没反应是什么原因?电脑usb接口没反应解决方法...
  4. 商云通安装(一):电信搭建SIP电话环境
  5. Kafka常用命令之kafka-topics.sh
  6. 基于Sentinel-1的干涉相干性特征生成
  7. [C语言]c语言之strcmp
  8. C语言getopt()函数
  9. 巴特沃斯数字低通滤波器的设计
  10. 用 Flask 来写个轻博客 (1) — 创建项目