Time-Traveler

时光旅人,向往美好

0%

TypeScript学习

1.基础

1.注解

  1. 声明变量类型

    1
    let a : number
  1. 声明函数的入参和出参类型

    1
    2
    3
    const fun1 = (arg1: number, arg2: number): number => {
    return arg1 + arg2
    }

2.类型

1.字面量

1
2
3
4
5
let a : 10
// 联合类型
let sex : "male" | "female"
sex = "male"
sex = "female"

2.any(不建议使用 )

关闭ts的类型检测

可以被赋值给所有类型的变量,也可以被所有类型的变量赋值

1
2
3
4
let b;
b = 1
b = '1'
b = true

3.unknown

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let a : 10 // any

let c : unknown
c = 1
c = '1'
c = true

// any与unknown的区别
let d : string
// any类型可以赋值给其他变量
d = b
// unknown类型不可以赋值给其他变量
// d = c
d = c as boolean

4.void

用于空返回类型

1
2
3
4
const fun2 = (arg: number): void => {
console.log(`输入结果是${arg}`)
}
fun2(200)

5.never(无法理解)

不能是任何值,用于报错返回

1
2
3
4
const fun3 = (): never => {
// throw new Error('抛出一个错误')
}
fun3()

6.object

  1. 指定变量类型为对象

    1
    2
    let O1 : object
    let O2 : {name: string}

01-let和const

01-共同特点

01-块级作用域

02-没有声明提升

03-不允许重复声明

02-const特有特点

01-声明不可变常量

02-不可变只针对简单的常量,复合常量只是表示指向的地址值不会变,但是内部的属性无法控制不变(const声明的对象和数组可以在后续进行相应的修改)

02-变量的解构

01-数组解构(按照顺序)

1
let [a, b, c] = [1, 2, 3];

02-对象解构(按照属性名)

1
let { bar, foo } = { foo: 'aaa', bar: 'bbb' };

03-默认值

1
2
let [a, b, c = 3] = [1, 2];
c //3

可以用于解构嵌套变量(如套娃json对象)

04-函数参数的结构赋值

按照传入参数的类型自行解构,解构失败使用默认值

05-圆括号慎用

等用到回来查

03-字符串扩展

01-for…of…遍历字符串内的每一个字符

02-unicode支持

03-模板语法

1
`/*模板内容*/`

可能会涉及<%%>转换问题,可以提前使用正则表达式解决

04-字符串新增方法

01-String.fromCodePoint()

正确返回Unicode码点对应的字符

02-String.raw()

生成一个把单斜杠变成双斜杠的字符换,常用语模板语法

03-codePointAt()

获得字符串某个下表字符的码点

04-normalize()

字符合成相关

05-includes(), startsWith() ,endsWith()

includes()是否包含, 第二个参数表示从第n个到结束

startsWith()是否开始于头部, 第二个参数表示从第n个到结束

endsWith()是否结束于尾部,第二个参数表示从开头到第n个,不包含

06-repeat()

返回调用该方法的字符串重复n次之后的字符串

07-padStart(),padEnd()

第一个参数表示规定的字符串长度

第二个参数表示用什么来补全

1
2
3
4
5
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'

'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'

08-trimStart(),trimEnd()

消除字符串前后的空格

09-matchAll()

返回一个正则表达式在当前字符串的所有匹配

05-正则扩展

跳过

06-数值扩展

01-二进制和八进制表示法

使用0b或者0B表示二进制前缀

使用0o或者0O表示八进制前缀

02-Number.isFinite(), Number.isNaN()

检测是否有限,是否为NaN

03-Number.parseInt(), Number.parseFloat()

04-Number.isInteger()

判断是否整数

对精度要求高不要使用

05-Number.EPSILON()

用于提供一个js能够识别的最小精度数字

用于解决类似0.1+0.2!==0.3的问题

06-安全整数和 Number.isSafeInteger()

判断是否安全整数

安全整数:整数范围在-2^532^53之间(不含两个端点)的数

07-Math对象扩展

01-Math.trunc()

去除小数部分,如4.5=》4,-4.5=》-4

02-Math.sign()

判断是正数负数还是零,返回值为+1,-1,0,NaN

03-Math.cbrt()

计算立方根

04-Math.clz32()

转换为32位无符号整数

05-Math.imul()

返回两个有符号32位整数相乘的结果

相对于a*b,优点在于溢出的时候可以正确返回低位的数值

06-Math.fround()

将64位双精度浮点数转换为32位单精度浮点数

07-Math.hypot()

返回所有参数的平方和的平方根

08-对数方法(略)

09-双曲函数方法(略)

08-指数运算符

1
2
2**3=8
2**2=4

09-BigInt数据类型

没有位数限制,不会像普通数值一样丢失精度,但是只能保存整数

表示方法

1
a = 123456789123456n

07-函数扩展

01-函数参数默认值

01-基本用法

1
2
3
function log(x, y = 'World') {
console.log(x, y);
}

02-可以与解构赋值语法一起使用

详情看上方解构赋值语法

03-有默认值的参数应该放后面

04-length问题

函数的length函数会返回该函数的参数个数,使用默认值会使计数粗线问题,返回0

05-作用域

参数使用默认值时,参数会自己形成一个作用域,先在当前作用域内找变量,再找外部变量

06-应用

可用于参数不得省略,用到再查

02-rest参数

01-用法

用于收集多余的参数

1
2
3
4
5
6
7
8
function add(...values) {
let sum = 0;
for (var val of values) {
sum += val;
}
return sum;
}
add(2, 5, 3) // 10

这个写法可以收集任意数量的参数,并进行数据运算

与arguments的区别,arguments是一个类似于数组的对象,但不是数组,想要使用数组的方法需要进行Array.prototype.slice.call进行转换才能使用数组方法

02-rest参数只能是最后一个参数

03-影响严格模式

使用默认值、解构赋值、或者扩展运算符,函数内部不能显式设置严格模式,否则报错

03-箭头函数

01-简单使用

1
2
3
4
5
6
var f = v => v;

// 等同于
var f = function (v) {
return v;
};

02-多个参数

1
var sum = (num1, num2) => { return num1 + num2; }

03-如果返回的参数是对象

1
let getTempItem = id => ({ id: id, name: "Temp" });

04-注意点

  1. this的指向问题,是指向定义时所在的对象,而不是使用时所在的对象
  2. 不可以当做构造函数
  3. 不可以使用arguments对象
  4. 不可以使用yield命令(这个命令没见过不知道做啥的,以后补充)

05-优点

可以用来封装回调函数,这样this只会指向创建他的对象,因此在外部调用这个方法的时候,不会因为this指向document而导致程序出错

这个优点同时也是缺点

当this需要动态变化和定义对象方法的时候,使用箭头函数会固化this指向,导致无法正确执行函数

04-尾调用优化

01-尾调用实例

1
2
3
function f(x){
return g(x);
}

最后一步调用另外一个函数,就是尾调用,只有像上面格式才是,其他无论长得多像都不是尾调用

02-尾调用的作用

在函数内调用另外一个函数的时候,需要保存父函数的作用域,存入到调用栈中,如果嵌套层数过多的话,会导致调用栈过于庞大,占用过多的内存。

所以使用尾调用,因为已经没有别的可以执行了,所以系统可以放心的把外层的调用帧释放掉,只生成内层函数的调用帧。

多使用尾调用,每次调用函数的调用帧就只有一层,可以大大节省内存空间

05-尾递归优化

01-尾递归

最后一步调用自身

02-尾递归的作用

当运行一些需要递归多次的算法的时候,容易发生栈溢出,使用尾递归可以把上层调用栈释放掉,阻止了栈溢出。

08- 数组扩展

01-扩展运算符

1
console.log(...[1, 2, 3])

会将数组拆分为逗号相隔的参数序列

01-数组复制

正常我们复制数组只是声明一个新的变量名,并让他指向旧数组的地址,使用旧变量名依然会影响新变量名。

使用扩展运算符可以使用类似于解构的语法来进行深拷贝。

1
2
3
4
5
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;

02-数组赋值

注意事项:用于数组赋值的时候,扩展运算符只能放在最后一步

03-拆分字符串

1
2
[...'hello']
// [ "h", "e", "l", "l", "o" ]

10-对象新增方法

03-Object.getOwnPropertyDescriptors()

01-主要作用

返回一个对象中所有的属性组合形成的对象,key为属性,value为该属性的描述对象,包括get&set方法,writeable:是否可读写,configurable:能否修改访问器属性,enumerable:是否可以使用for in循环出来。

补充重新理解的点:

01-call()和apply()

主要作用都是改变this的指向

1
2
A.call(B,arg1,arg2,arg3)
A.apply(B,args)

以上都是使用A的方法,只不过this这个时候指向B

可以理解为B使用了A的方法

02-get&set方法

类内部自带的方法,重写之后,涉及到属性的修改或者获取的操作时,会执行方法的逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Num {
constructor(num) {
this._num = num;
}

get num() {
return this._num;
}

set num(num) {
this._num = num+1;
}
}

var test = new Num(9);
console.log(test.num); //9
test.num = 99;
console.log(test.num); //100

有点难理解的点:

箭头函数,this的指向问题

mutation与action的区别

Mutation:必须同步执行。

Action:可以异步,但不能直接操作State。

定位

1.粘性定位

用于快速实现滚动吸顶的效果,似乎兼容性不是特别优秀,特别是移动端

1
position: sticky

1、父元素不能overflow:hidden或者overflow:auto属性。

2、必须指定topbottomleftright4个值之一,否则只会处于相对定位

3、父元素的高度不能低于sticky元素的高度

4、sticky元素仅在其父元素内生效

安装

1
npm install axios --save

基本命令

1
2
3
4
5
6
7
8
axios.request(config)
axios.get(url[, config])
axios.delete(url[, config])
axios.head(url[, config])
axios.options(url[, config])
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
axios.patch(url[, data[, config]])

小试

1.JS基础

1.JS中将数组所有元素放到字符串中,并以”,”分隔()

1
join(",")

2.HTML5的Web存储对象有两个,分别是1和 2

1
2
3
4
// 1:
localStorage
// 2:
sessionStorage

3.描述一下脚本script标签放在head标签和放到body标签底部的区别

1
2
3
放<head>中的情况:脚本会优先加载,但加载过程中,<body>还没加载完,会使脚本访问不到<body>中的元素。
放<body>底部:脚本在<body>加载后加载,能够保证脚本有效地访问<body>的元素。
例外情况:脚本中没有访问<body>元素的情况下,两种加载方式效果一致。

2.ES6

3.CSS

1.CSS3中,能使用div的宽度变化有2秒的过渡效果的属性是

1
2
3
div {
transition: width 2s;
}

4.HTTP

1.Http请求返回码(status code)中,代表[未授权的请求]的代码是

1
401

需要补充的知识

ES6解构语法

备注:

本文收录一些脚手架的配置信息,以及一些开发过程必要的操作

1.删除目录中不需要的资源

image-20200923110304550

先把不必要的资源给删了

2.在compoments添加公共index.vue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<template>
<div>
<h2>这里是index页面</h2>
</div>
</template>

<script>
export default {
name: "",
components: {},
props: {},
data() {
return {
};
},
watch: {},
computed: {},
methods: {},
created() {},
mounted() {}
};
</script>
<style scoped>

</style>

创建个人模板可以查看网上教程

3.配置vue-router

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import Vue from 'vue'
import Router from 'vue-router'

const Index=()=>import('../components/index')

Vue.use(Router)

export default new Router({
routes: [
{
path: '',
redirect: '/index',
},
{
path: '/index',
name: 'index',
component: Index
},
]
})

修改app.vue文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<div id="app">
<router-view></router-view>
</div>
</template>

<script>
import Index from './components/index'
export default {
name: 'App',
components: {
Index
}
}
</script>

<style>

</style>

4.安装vuex组件

在项目主目录运行

1
npm install vuex --save

在src目录下添加store文件夹,创建index.js文件

初始化以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

const store = new Vuex.Store({
state:{
testInfo: '测试vuex'
},
mutations:{},
getters:{},
actions:{},
modules:{}
})

export default store;

给**./compoments/index.vue** 的tamplate添加以下内容

1
2
3
4
5
6
7
<template>
<div>
<h2>-----这里是index页面-----</h2>
<h2>-----vue测试-----</h2>
<div>{{$store.state.testInfo}}</div>
</div>
</template>

main.js修改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import Vue from "vue";
import App from "./App";
import router from "./router";
import store from './store';

Vue.config.productionTip = false;

new Vue({
el: "#app",
router,
store,
components: { App },
template: "<App/>"
});

5.为文件夹添加别名

目的是为了在后期文件结构复杂的时候,可以快速定位到相应的文件夹

不用担心改一下文件位置就得修改大部分文件路径

在主目录下添加vue.config.js文件,初始化以下内容

1
2
3
4
5
6
7
8
9
10
11
12
module.exports = {
configureWebpack: {
resolve: {
alias: {
//配置别名,修改后需要重新编译才能生效
assets: "@/assets",
components: "@/components",
views: "@/views",
},
},
},
};

6.添加公共css文件

在/assets/css文件夹中添加base.css

公共样式卸载里面

然后在main.js中引入

1
require('./assets/css/base.css');

启动项目

1
npm run dev

打开网页

1
http://localhost:8080/#/index

image-20200923113735138

1.使用场景

有异步操作的时候,会使用Promise对这个操作进行封装,防止套娃

2.基本结构

处理形式1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
new Promise((resolve, reject) => {
// 使用setTimeout模拟请求数据的异步操作
setTimeout(() => {
// 成功的时候执行resolve
resolve(data.id);
// 失败的时候执行reject
reject(err);
}, 1000);
})
.then((data) => {
// 这里data就是上面resolve的参数
// 数据的处理过程
})
.catch((err) => {
// 错误信息展示
});

处理形式2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
new Promise((resolve, reject) => {
// 使用setTimeout模拟请求数据的异步操作
setTimeout(() => {
// 成功的时候执行resolve
resolve(data.id);
// 失败的时候执行reject
reject(err);
}, 1000);
}).then(
(data) => {
// 这里data就是上面resolve的参数
// 数据的处理过程
},
(err) => {
// 错误信息展示
}
);

3.两种简写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Jamie");
}, 1000);
})
.then((data) => {
// 正常写法
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(data.toLocaleLowerCase());
}, 1000);
});
})
.then((data) => {
console.log(data);
data += " Wang";
// 初级简写
return Promise.resolve(data + " Chi");
})
.then((data) => {
console.log(data);
// 超级简写
return data + " Jie";
})
.then(data => console.log(data));

4.多异步操作写法

1
2
3
4
5
6
7
8
9
10
11
12
Promise.all([
new Promise((resolve, reject) => {
// 异步请求1:
resolve('res1')
}),
new Promise((resolve, reject) => {
// 异步请求2
resolve('res2')
}),
]).then((results) => {
console.log(results);
})

重要单词

sync

synchronization [ˌsɪŋkrənaɪ’zeɪʃ(ə)n] 同步

async

asynchronization 异步

display:flex布局加position:fixed注意事项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#tab-bar {
display: flex;
height: 49px;
background-color: #f6f6f6;
position: fixed;
left: 0;
right: 0;
bottom: 0;
}

.tab-bar-item {
flex: 1;
height: 100%;
height: 49px;
text-align: center;
}

这里同时left:0和right:0是防止定位后,子元素没有像预期那样均分