0%

ES6

ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

模块化

export require是CommonJS规范的方法,es6 引入了import,可以将模块中的对象部分引入,以减少开销,或者使用import as objName from 引入文件所有对象
CommonJS vs ES Modules:
*nodejs是默认使用CommonJS的
,其表现可见express的服务中,如”module.exports = AssetService;”以及”var AssetService = require(‘./AssetService’)”。而es6中用”import common from ‘@myRepo/core’”和”export ..”
更多了解NodeJS Docs

Caution: the semicolon at the end of the import is mandatory!

1
2
3
4
/*util1.js*/
export default{
a:100
}

1
2
3
/*index.js*/
import util1 from './util1.js'
console.log(util1)

动态引入
1
2
3
4
5
6
import('/modules/my-module.js')
.then((module) => {
// Do something with the module.
});
// OR
let module = await import('/modules/my-module.js');

MDN:import
据说动态import的模块在打包时会自动分割,见React Docs: 代码分割

关于声明

let 代替 var. 同一变量不能重复使用let声明, 否则报错

const是常量,区别于只读

1
2
const s = [1];
s[0]=0;

但是可以用Object.freeze()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function freezeObj() {
"use strict";
const MATH_CONSTANTS = {
PI: 3.14
};
Object.freeze(MATH_CONSTANTS)
try {
MATH_CONSTANTS.PI = 99;
} catch( ex ) {
console.log(ex);
}
return MATH_CONSTANTS.PI;
}
const PI = freezeObj();

Object.assign()

将所有可枚举属性的值从一个或多个源对象复制到目标对象

Object.assign(target, …sources)

1
2
3
4
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source); // expected output: Object { a: 1, b: 4, c: 5 }

用法用途

  • 浅拷贝 cloneObj = Object.assign({}, …sources)
  • 覆盖目标同名属性
  • 合并数组 实际上是覆盖序号属性值 即Object.assign([1,2,3], [4,5]) // [4,5,3]

    箭头函数表达式

    1
    2
    3
    const squaredIntegers = arr.filter(item=>{
    return Math.floor(item)===item&&item>0 ;
    }).map(item=>Math.pow(item, 2))
    箭头表达式牵扯到的一个知识点是“箭头表达式不会创建this”
    需知javascript this是区分运行环境的标记,见 阮一峰 JavaScript 的 this 原理,箭头表达式继承外层函数运行环境。

关于省略,函数体只有一个return语句时,可省略return关键字和花括号

1
2
func = x => { return x+1;}
func = x => (x+1)

剩余参数运算符(Rest Operator)

使用Rest Operator定义参数数量可变的函数,参数将存入Rest Operator指定的变量指代的数组中

1
2
3
4
function howMany(...args) {
return "You have passed " + args.length + " arguments.";
}
console.log(howMany(0, 1, 2)); // You have passed 3 arguments

1
2
3
4
5
6
7
8
const sum = (function() {
"use strict";
return function sum(...args) {
//const args = [ x, y, z ];
return args.reduce((a, b) => a + b, 0);
};
})();
console.log(sum(1, 2, 3)); // 6

回顾下归并方法reduce,array.reduce(callback,[, initialValue]),callback接受以下参数:previousValue,前一次调用回调函数的返回值;currentValue当前处理的数组元素,currentIndex可选,当前数组元素下标;array可选,调用reduce()方法的数组。initialValue可选,作为第一次调用callback方法的previousValue参数
1
2
3
4
5
6
var arr = [6, 89, 3, 45];
var maximus = Math.max.apply(null, arr); // returns 89
maximus = Math.max(...arr); // returns 89

arr0 = [...arr]
console.log(arr0==arr) // false

解构赋值(Destructuring Assignment)

1
2
var voxel = {x: 3.6, y: 7.4, z: 6.54 };
const { x, y, z } = voxel; // x = 3.6, y = 7.4, z = 6.54

或者将部分属性 voxel.x, voxel.y 存入指定变量 a, b

1
const { x : a, y : b} = voxel // a = 3.6, b = 7.4

分离多余的变量
1
2
let postData = Object.assign({ extraAttr:'extra' }, dto);
let { extraAttr, ...entity } = postData;

嵌套对象(nested objects)
1
2
3
4
5
6
7
8
9
10
11
const tree = {
text:'A',
value:0,
parentNode:{
text:'Root',
value:-1
}
}

const {parentNode:{value:RootVal}} = tree;
console.log(RootVal)

数组
1
2
3
4
const [a, b,,, c] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c); // 1, 2, 5
// use rest operator
const [begining,...rest] = [1, 2, 3, 4, 5, 6];

交换值
1
[a, b] = [b, a];

函数传参
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const stats = {
max: 56.78,
standard_deviation: 4.34,
median: 34.54,
mode: 23.87,
min: -0.75,
average: 35.85
};
const half = (function() {
"use strict";
return function half({max,min}) {
return (max + min) / 2.0;
};
})();
console.log(half(stats)); // 28.015

ES9 剩余运算符可应用于解构语法

字符串模块(Template Literals)

1
2
3
resultDisplayArray = arr.map(item=>{
return `<li class="text-warning">${item}</li>`
});

简化声明

1
2
3
4
5
6
const person = {
name: "Taylor",
sayHello: function() {
return `Hello! My name is ${this.name}.`;
}
};

可写作

1
2
3
4
5
6
const person = {
name: "Taylor",
sayHello() {
return `Hello! My name is ${this.name}.`;
}
};

class 以及 get set 以及super

1
2
3
4
5
6
7
8
9
10
11
12
13
class Book {
constructor(author) {
this._author = author;
}
// getter
get writer(){
return this._author;
}
// setter
set writer(updatedAuthor){
this._author = updatedAuthor;
}
}

Promise

区别于回调函数方式的异步编程方案, ES6将其写入语言标准。

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。

Promise对象的状态

pending(进行中)、fulfilled(已成功)和rejected(已失败)只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function loadImageAsync(url) {
return new Promise(function(resolve, reject) {
const image = new Image();

image.onload = function() {
resolve(image);
};

image.onerror = function() {
reject(new Error('Could not load image at ' + url));
};

image.src = url;
});
}

加载图片的异步过程,成功或失败时触发相应的事件(load,error),resolve和reject刚好对应作为事件响应方法

// TODO Promise 链式调用(存目)

Promise().then(…)的第二个参数可以捕捉异常,和链式调用最后的catch有和区别?

catch只是一个语法糖而己 还是通过then 来处理的,大概如下所示

1
2
3
Promise.prototype.catch = function(fn){
return this.then(null,fn);
}

generator

以function*定义的生成器,与function的区别是除了return,其执行期间可以yield‘返回’多次

1
2
3
4
5
function* foo(x) {
yield x + 1;
yield x + 2;
return x + 3;
}

斐波那契生成器
1
2
3
4
5
6
7
8
9
10
11
12
13
function* fib(max) {
var
t,
a = 0,
b = 1,
n = 0;
while (n < max) {
yield a;
[a, b] = [b, a + b];
n ++;
}
return;
}

fib(5)返回一个generator对象console输出形如fib {[[GeneratorStatus]]: “suspended”, [[GeneratorReceiver]]: Window}
调用generator对象的next方法迭代
1
2
3
4
5
6
7
var f = fib(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: false}
f.next(); // {value: undefined, done: true}

也可以var x of fib(5)进行迭代,x即value
generator似乎是为了状态管理而生的工具,所谓状态管理,因为其表象是一步接一步(next)来的,后面步骤的结果有可能需要依赖前面一步的状态(比如成功或失败,抑或current result)
async await是generator的语法糖

关于迭代器和可迭代对象
迭代器是使用next()方法实现迭代器协议(lterator protocal)的任意对象,如Array迭代器
可以使用for of迭代的对象即可迭代对象

ES7

Array.protorype.includes

array.includes(x) 相当于 array.indexOf(x)

ES6中已添加了String.prototype.includes

指数运算符 **

1
2
2 ** 2 // 4
2 ** 3 // 8

js引擎(V8)对**的实现与Math.pow的运算结果是会有差别的

ES8

字符串填充

以指定字符/字符串/函数方式, 在首或尾填充字符串至特定长度

1
2
3
str.padStart(targetLength [, padString])

str.padEnd(targetLength [, padString])

Object.values, Object.entries

获取对象属性值的集合

1
2
const obj = { x: 'xxx', y: 1 };
Object.values(obj); // ['xxx', 1]

其实现是for in,因此obj也可以是Array或string,其输出结果也是遍历逐个下标组成的集合。

获取对象键值对的集合

1
2
const obj = { x: 'xxx', y: 1 };
Object.entries(obj); // [['x', 'xxx'], ['y', 1]]

async, await

async(asynchronous)异步

await(asynchronous wait)等待异步结果
下面的代码结构被称作callback hell
其需求是从input.xml文件中读取action,如果action=token,则读取注册表,验证token时效,其中读文件,xml转json,读注册表均为异步操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
(function(){
fs.readfile('input.xml',(err,data)=>{
if(err){
console.error(err)
}else{
regedit.list('HKCU\Software\QQSTEST\',(err,data)=>{
if(err){
console.error(err)
}else{
xmlParser.parseString(data,(err,data)=>{
if(err){
console.error(err)
}else{
done(data)
}
})
}
})
}
})
})()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function readfileAsync(filepath){
return new Promise((resolve,reject)=>{
fs.readFile(filepath,(err,data)=>{
if(err){
reject(err)
}else{
resolve(data)
}
})
})
}
(async function(){
var fileData = '';
await readfileAsync('input.xml).then(data=>{
fileData=data;
},err=>{
console.log(err)
})
if(!fileData) return;
await readRegEditAsync('')
})()

在async声明的function内使用await, 执行时等待promise对象的结果,完成其resolve或reject操作后向下执行。

Caution! 在forEach中加async await不能阻塞循环,事实上forEach回调函数无法跳出循环,不要在forEach里面使用async-await、break、return,在有相关需求的场景下使用for循环语法
Q160解析

见下文 ES 9 异步迭代

ES9

异步迭代

1
2
3
4
5
async function process(array) {
for await (let i of array) {
doSomething(i);
}
}

Promise.finally

1
2
3
iPromise.then(do_sth1).then(do_sth2)
.catch(err_handle)
.finally(complete_handle)

在正则表达式中命名模式匹配结果

模式指使用()封装的规则,在ES9中可以用(?\)的方式封装,在之后的js逻辑中,可以使用命名变量

1
2
3
4
// 将"年-月-日"改为"月-日-年"
const reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
d = '2018-04-30',
usDate = d.replace(reDate, '$<month>-$<day>-$<year>');

正则表达式断言和反向断言

正则表达式

正则表达式dotAll

正则表达式中点.匹配除回车外的任何单字符,标记s改变这种行为,使之匹配包含终止符的所有字符,例

1
2
/hello.world/.test('hello\nworld');  // false
/hello.world/s.test('hello\nworld'); // true

正则表达式 Unicode 转义

转义语法\p{…}

1
2
const reGreekSymbol = /\p{Script=Greek}/u;
reGreekSymbol.test('π'); // true

ES10

Array.prototype.flat, flatMap

可指定层次数(允许Infinity)迭代遍历,输出元素的集合 ———— 数组降维

1
2
3
var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2); // [1, 2, 3, 4, 5, 6]


flat自动移除空项

Array.prototype.flatMap

如array.map(callback)一样遍历每个元素,之后,把运算结果“压平”成一个数组,QQs:不如改叫mapFlat

1
2
[1,2,3].flatMap(i=>{return new Array(i).fill(i)})
// output: [1, 2, 2, 3, 3, 3]

String.prototype.trimStart, trimEnd

去除首/尾的空白字符

Object.prototype.fromEntries

是ES8 Object.entries 的反向操作

String.prototype.matchAll

返回匹配正则表达式的所有结果的集合

新增基本数据类型 BigInt

js基本数据类型(值类型)已不止5种(ES6之后是六种)!ES10后一共有七种基本数据类型,分别是: String、Number、Boolean、Null、Undefined、Symbol、BigInt

关于Symbol,生成唯一的值,用于不关心具体值的场景 见知乎:JS 中的 Symbol 是什么?

装饰器Decorator

Angular常见的@Component(), @Module()等,在Ts中已有规范
ES6 提案 尚未标准化,js decorator或无法被浏览器适用,需使用babel打包并规范化
其实质是将定义的方法(装饰器名即函数签名)添加到紧随其后的class, function的propotype上

1
2
3
4
5
6
7
8
9
10
11
// 例如 mobx 中 @observer 的用法
/**
* 包装 react 组件
* @param target
*/
function observer(target) {
target.prototype.componentWillMount = function() {
targetCWM && targetCWM.call(this);
ReactMixin.componentWillMount.call(this);
};
}

关注木易杨每日面试题

Daily Interview Question

知乎专栏:flex
display: flex

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<style>
#box-container {
height: 500px;
display: flex;
}

#box-1 {
background-color: dodgerblue;
width: 50%;
height: 50%;
}

#box-2 {
background-color: orangered;
width: 50%;
height: 50%;
}
</style>
<div id="box-container">
<div id="box-1"></div>
<div id="box-2"></div>
</div>

flex-direction

value: row | column | row-reverse | column-reverse

justify-content

value: flex-start | flex-end | space-betwee | space-around
子元素不占满父元素时,在水平方向设置排列和空余的选项

align-items

value: flex-start | flex-end | space-betwee | space-around
子元素不占满父元素时,在垂直方向设置排列和空余的选项

align-content
value: flex-start | flex-end | center | strech | space-betwee | space-around

flex-wrap

value: nowrap | wrap | wrap-reverse
当子元素宽度之和超过弹性布局容器时,设置换行

flex-shrink

value:(number)
设置子元素在弹性布局容器中的宽度压缩比例

flex-grow

value:(number)
设置子元素在弹性布局容器中的高度拉伸比例

flex-basis

value:(px, em, %)
在进行flex-shrink和flex-grow前初始化子元素尺寸

缩写

1
2
3
4
5
flex: 1 0 10px;
// same as
flex-grow: 1;
flex-shrink: 0;
flex-basis: 10px;

order
value:(number)
次序

align-self

value:auto | flex-start | flex-end | center | baseline | stretch | inherit
设置在各子元素与父元素的align-item作用对应并覆盖align-item效果

从原理出发

标记为 display:flex | inline-flex 的块状元素(即flex container)获得控制其子元素(flex item)宽高或顺序的能力

子元素沿main axis均匀排布(just-content)沿cross axis调整对齐(align-item)
main axis未必是水平的 由flex-direction控制

  • just-content控制沿主轴的排布


所有子元素都沿主轴排布 所以是调整‘content’

  • align-item控制cross axis方向上的对齐


每个子元素在其侧轴上 与其他子元素对其 所以是对其‘item’

  • align-content
    顾名思义 对其所有元素 应用于 超出一行 且未占满整个container的情形

Angular Doc: 路由
在AppComponent初始化登录服务,其中有request发送到后台,报401,有HttpInterceptor拦截401,且有RoutGuard校验登录成功后的数据,该场景下HttpInterceptor先生效,因token失效而做重定向,然后RoutGuard生效,二者依据有所区别,固行为有所冲突。现workaround是避免在初始化Angular App或初始化登录模块时调用有可能被HttpInterceptor拦截的接口

查询列表与详情页的路由跳转

从指定查询条件的列表,路由到详情页,以及从详情页返回原查询结果页
list component

1
this.router.navigate([`/asset/list/detail/${dataItem.asset_id}`], {queryParams: this.s})

detail component
1
2
3
4
5
6
7
8
9
10
queryParam:any
// init
this.route.paramMap.subscribe(params => {
const id = +params.get('id');
this.getAsssetById(id);
});
this.route.queryParamMap.subscribe(queryParam=>this.queryParams=queryParam)

// return
this.router.navigate(['../'], {queryParams: this.queryParams});

Hash:false

去掉url的#

useHash:false的情况下navigateByUrl完整的url出现404,相对路由路径正常

apache配置

1
a2enmod rewrite

出于复用需要的函数封装

典型的函数库Jquery

匿名函数

1
2
3
function(){

}

匿名函数使用

1
2
3
4
func1=function(){
console.log(1);
}
func1();

考点:下面的代码输出结果
1
2
3
var func=function a(){};
console.log(func);
console.log(a);

答案:function undefined
这个叫具名函数表达式
变量func引用函数体,虽然该函数具有函数名a 实际上 函数名a仅在其函数体内部有效

自执行函数
1
2
3
(function(){
console.log(1);
})()

function外面的括号()消除歧义1

使用自执行函数创建命名空间

1
2
3
4
5
6
7
var qqsNamespace = function(){
var func1 = function(parameter1,parameter2){
console.log('func1');
}
return {action:func1}
}();
qqsNamespace.action(1,2);

所谓创建命名空间,模仿了块级作用域,调用匿名函数生成一个对象Lib,对象Lib内部定义了自己的方法,使用时根据需要从生成的对象Lib中调用

JQuery

实现字符串翻转方法

1
2
3
4
5
6
function reverseString(str) {
var litters=str.split("");
var rlitters=litters.reverse();
return rlitters.join("");
}
reverseString("hello");

区分String方法split以及Array方法slice, splice

split 以特定字符或正则表达式为标记,将字符串分割为字符串数组
slice 以起止下标为界切片返回新数组,原数组不受影响
splice 以起止下标为界切片从数组中剔除

常用到的将含length的对象转为数组用

1
Array.prototype.slice.call(a)

实现数字千位分隔符

1
2
3
4
5
6
7
8
9
10
11
function kiloFormat(num){
num=num.toString().split(".");//区分整数部分和小数部分
num[0]=num[0].split("").reverse();//整数部分数组化并翻转
num[0]=num[0].map((item,i)=>{
if(i%3==0&&i!=0){
return item+=",";
}else{return item;}
});
num[0]=num[0].reverse().join("");
return num.join(".");
}

1
2
3
4
5
6
7
8
// 另 正则表达式实现
function thousandBitSeparator(num) {
return num && num
.toString()
.replace(/(\d)(?=(\d{3})+\.)/g, function($0, $1) {
return $1 + ",";
});
}

标题

1

1.1

1.1.1

1.1.1

1.1.1 a
1
2
3
var a="1";
a+=2;
print a;

这一段,

引言


叫区块引用

斜体
加粗
删除线
下划线

  • 第一教条
  • 第二条
  1. 首先
  2. 然后
  3. 最后
  • Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
    viverra nec, fringilla in, laoreet vitae, risus.
  • Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
    Suspendisse id sem consectetuer libero luctus adipiscing.

这个是百度链接 可以使用相对路径

QQstone笔记

根据某某某考证,见[该刊]1

站内超链接:关于websockt 详见 WebSocket篇

1
{% post_link 文章文件名 显示文字 %}

反引号``取消自动超链接: https://www.baidu.com 但是有个高亮背景,或者用\

cannot load pic here

左对齐 居中 右对齐
内容 内容 内容
内容 内容 内容

console.log('code here')

1
console.log('code here')

矩阵

更多数学表示—> CSDN: nuoyanli
公式的语法是mathjax的规范 hexo-js-next渲染公式需用hexo-renderer-kramed(默认是hexo-renderer-marked)
配置theme\next_config.yml mathjax: enable: true
同时在文章title下使能 mathjax: true
详见hexo-theme-next doc:数学公式

PlantUML绘图

安装VS Code插件: Markdown Preview Enhanced, PlantUML

```plantuml
@startuml

== Initialization ==

Alice -> Bob: : Can you solve: ax^2+bx+c=0
Bob —> Alice: x = (-b+-sqrt(b^2-4ac))/(2a)
activate Alice #FFBBBB
note left: this is a first note

Alice -> Bob: Another dialogue
deactivate Alice

Alice <— Bob: Another dialogue

@enduml
```@enduml