🎀大更新:webp、valine、gulp
6
.github/workflows/hexo_deploy.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: npm -v
|
||||
- run: apt install yarn -y
|
||||
|
||||
- name: setup hexo env
|
||||
env:
|
||||
@ -46,6 +46,4 @@ jobs:
|
||||
- name: deploy
|
||||
run: |
|
||||
# publish
|
||||
hexo cl
|
||||
hexo g
|
||||
hexo d
|
||||
yarn go
|
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"compile-hero.disable-compile-files-on-did-save-code": false
|
||||
}
|
12
Dockerfile
Normal file
@ -0,0 +1,12 @@
|
||||
FROM node:15.0.1-alpine as builder
|
||||
WORKDIR /root
|
||||
COPY ./ ./
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
|
||||
&& apk update \
|
||||
&& apk upgrade \
|
||||
&& apk add --no-cache yarn \
|
||||
&& yarn \
|
||||
&& yarn run go
|
||||
|
||||
FROM nginx:alpine
|
||||
COPY --from=builder /root/public/ /usr/share/nginx/html
|
33
Gulpfile.js
Normal file
@ -0,0 +1,33 @@
|
||||
const { series, parallel } = require('gulp');
|
||||
const { src, dest } = require('gulp');
|
||||
const cleanCSS = require('gulp-clean-css');
|
||||
const htmlmin = require('gulp-htmlmin');
|
||||
const uglify = require('gulp-uglify-es').default;
|
||||
const htmlclean = require('gulp-htmlclean');
|
||||
|
||||
function html() {
|
||||
return src('./public/**/*.html')
|
||||
.pipe(htmlclean())
|
||||
.pipe(htmlmin({
|
||||
collapseWhitespace: true,
|
||||
removeComments: true,
|
||||
minifyJS: true,
|
||||
minifyCSS: true,
|
||||
minifyURLs: true
|
||||
}))
|
||||
.pipe(dest('./public'))
|
||||
};
|
||||
|
||||
function css() {
|
||||
return src('./public/**/*.css')
|
||||
.pipe(cleanCSS())
|
||||
.pipe(dest('./public'))
|
||||
};
|
||||
|
||||
function js() {
|
||||
return src('public/**/*.js')
|
||||
.pipe(uglify())
|
||||
.pipe(dest('./public'))
|
||||
}
|
||||
|
||||
exports.default = parallel(html, css, js);
|
1000
_config.fluid.yml
9777
package-lock.json
generated
12
package.json
@ -6,7 +6,9 @@
|
||||
"build": "hexo generate",
|
||||
"clean": "hexo clean",
|
||||
"deploy": "hexo deploy",
|
||||
"server": "hexo server"
|
||||
"server": "hexo server",
|
||||
"dev": "hexo cl && hexo g && gulp",
|
||||
"go": "hexo cl && hexo g && gulp && hexo d"
|
||||
},
|
||||
"hexo": {
|
||||
"version": "5.2.0"
|
||||
@ -14,14 +16,11 @@
|
||||
"dependencies": {
|
||||
"babel": "^6.23.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-babel": "^8.0.0",
|
||||
"gulp-clean-css": "^4.3.0",
|
||||
"gulp-eslint": "^6.0.0",
|
||||
"gulp-htmlclean": "^2.7.22",
|
||||
"gulp-htmlmin": "^5.0.1",
|
||||
"gulp-imagemin": "^7.1.0",
|
||||
"gulp-shell": "^0.8.0",
|
||||
"gulp-uglify": "^3.0.2",
|
||||
"gulp-uglify-es": "^2.0.0",
|
||||
"hexo": "^5.2.0",
|
||||
"hexo-cli": "^4.2.0",
|
||||
"hexo-deployer-git": "^2.1.0",
|
||||
@ -35,8 +34,7 @@
|
||||
"hexo-renderer-marked": "^3.3.0",
|
||||
"hexo-renderer-stylus": "^2.0.1",
|
||||
"hexo-server": "^2.0.0",
|
||||
"hexo-theme-fluid": "^1.8.4",
|
||||
"mozjpeg": "^7.0.0"
|
||||
"hexo-theme-fluid": "^1.8.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.3",
|
||||
|
7
source/_data/添加水印.xbs
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><XnView_script version="1.0" name="添加水印">
|
||||
<Watermark filename="C:/Users/Defectink/OneDrive/Pictures/Logo/文字logo标题.png" opacity="85" no_alpha="false" position="8" delta_x="-25" delta_y="-25" perc="15" size="3"/>
|
||||
<Output folder="" filename="{Filename}" case="0" startIndex="1" format="WEBP">
|
||||
<Options overwrite="1" orgDate="false" keepMeta="false" keepICC="false" keepFolder="false" keepParentFolder="false" keepExtension="true" delOrg="true" multipage="false" allPages="false" openExplorer="false" openBrowser="false" clearItems="false"/>
|
||||
<WEBP method="0" quality="75" filesize="128" compress="4" strength="60" sharpness="0" preset="0"/>
|
||||
</Output>
|
||||
</XnView_script>
|
6
source/_data/转换webp.xbs
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><XnView_script version="1.0" name="转换webp">
|
||||
<Output folder="" filename="{Filename}" case="0" startIndex="1" format="WEBP">
|
||||
<Options overwrite="1" orgDate="false" keepMeta="false" keepICC="false" keepFolder="false" keepParentFolder="false" keepExtension="true" delOrg="true" multipage="false" allPages="false" openExplorer="false" openBrowser="false" clearItems="false"/>
|
||||
<WEBP method="0" quality="75" filesize="128" compress="4" strength="60" sharpness="0" preset="0"/>
|
||||
</Output>
|
||||
</XnView_script>
|
@ -1,81 +0,0 @@
|
||||
---
|
||||
title: ES6解构赋值
|
||||
index_img: /images/
|
||||
date: 2020-08-30 16:50:30
|
||||
tags:
|
||||
categories:
|
||||
url:
|
||||
---
|
||||
|
||||
|
||||
解构赋值是一种JavaScript的语法表达式,通过解构赋值,可以将属性/值从对象/数组等中提取出来,赋值给其他变量。
|
||||
|
||||
基本规则:
|
||||
|
||||
1. 数组的元素是按次序排列的,变量的取值由它的位置决定;
|
||||
2. 对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
|
||||
|
||||
解构赋值采用和字面量类似的表达式,不同的是在表达式左边定义了要从原变量中提取出什么变量。
|
||||
|
||||
## 语法
|
||||
|
||||
```js
|
||||
var a, b, rest;
|
||||
[a, b] = [10, 20];
|
||||
console.log(a); // 10
|
||||
console.log(b); // 20
|
||||
|
||||
[a, b, ...rest] = [10, 20, 30, 40, 50];
|
||||
console.log(a); // 10
|
||||
console.log(b); // 20
|
||||
console.log(rest); // [30, 40, 50]
|
||||
|
||||
({ a, b } = { a: 10, b: 20 });
|
||||
console.log(a); // 10
|
||||
console.log(b); // 20
|
||||
|
||||
|
||||
// Stage 4(已完成)提案中的特性
|
||||
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
|
||||
console.log(a); // 10
|
||||
console.log(b); // 20
|
||||
console.log(rest); // {c: 30, d: 40}
|
||||
```
|
||||
|
||||
```js
|
||||
var x = [1, 2, 3, 4, 5];
|
||||
var [y, z] = x;
|
||||
console.log(y); // 1
|
||||
console.log(z); // 2
|
||||
```
|
||||
|
||||
## 数组
|
||||
|
||||
数组的解构赋值是按顺序排列的,变量的取值由他的位置决定。先来几个简单的例子:
|
||||
|
||||
```js
|
||||
let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
|
||||
let [a, b, c, d] = arr;
|
||||
|
||||
console.log(a, b, c, d); // 1, 2, 3, 4
|
||||
```
|
||||
|
||||
与一般的字面量赋值不同,解构赋值数组是将等式由边的数组按顺序赋值给左边的变量。
|
||||
|
||||
### 默认值
|
||||
|
||||
当然等式的左右两边长度可能不一样,没有获取到值的变量会被声明为undefined,就和只声明不赋值变量一样。
|
||||
|
||||
不过解构赋值还可以为其赋予一个默认值,这样变量在为获取到值的情况下就会被赋予到默认的值。
|
||||
|
||||
```js
|
||||
let [a = 123, b = 123] = [1];
|
||||
// a: 1;
|
||||
// b: 123;
|
||||
```
|
||||
|
||||
|
||||
|
||||
```
|
||||
[结构赋值|MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
|
||||
```
|
69
source/_md/探索Node.js基本概念.md
Normal file
@ -0,0 +1,69 @@
|
||||
为了深入了解同步与异步编程,和充分理解这一理念。打算详细的了解与对比这两种编程模式。
|
||||
|
||||
## Node编程风格
|
||||
|
||||
随便搜寻几篇Node.js的文章便会发现,node主要的编程风格便是使用非阻塞(异步)编码风格。先通过一个日常的举例来了解下阻塞(同步)编码与非阻塞(异步)编码之间的差异。
|
||||
|
||||
## 同步与异步的对比 – 场景一
|
||||
|
||||
Node.js 官网关于阻塞式 I/O 的定义如下:
|
||||
|
||||
> “阻塞表示 Node.js 进程中其他 JavaScript 的执行必须等到非 JavaScript 操作完成后才能继续的情况。发生这种情况的原因在于,当发生阻塞操作时,事件循环无法继续运行 JavaScript。
|
||||
> 在 Node.js 中,由于 CPU 占用率高而不是等待非 JavaScript 操作(如 I/O)导致性能欠佳的 JavaScript 通常并不被称为阻塞。”
|
||||
|
||||
### 同步
|
||||
|
||||
普通的同步风格程序。它在 V8 线程上自上而下运行,仅占用少量 CPU,这是非技术层面的阻塞。
|
||||
|
||||
```js
|
||||
'use strict'
|
||||
console.log(Date.now().toString() + ': 主进程开始;');
|
||||
console.log(Date.now().toString() + ': 创造一个延迟;');
|
||||
let start = Date.now();
|
||||
let end = start;
|
||||
while(end < start + 20) {
|
||||
end = Date.now(); // 阻塞延迟
|
||||
}
|
||||
console.log(Date.now().toString() + ': 主进程结束;');
|
||||
```
|
||||
|
||||
这里使用了`while`通过不断的检查系统时间来创建一个阻塞的延迟动作,根据最后打印的时间戳,总共运行时间在21~23毫秒之间。
|
||||
|
||||
### 异步
|
||||
|
||||
使用异步的方式创建了与上述同样效果的实例。
|
||||
|
||||
```js
|
||||
'use strict'
|
||||
console.log(Date.now().toString() + ': 主进程开始;');
|
||||
setTimeout(() => {
|
||||
console.log(Date.now().toString() + ': 事件循环回调');
|
||||
}, 20);
|
||||
console.log(Date.now().toString() + ': 主进程结束;');
|
||||
```
|
||||
|
||||
这里的异步使用了`setTimeout`来将事件超时运行。根据最后打印的时间戳,总共运行时间在25~30毫秒之间。
|
||||
|
||||
## 场景一小结
|
||||
|
||||
经过上述的小实验,不难发现同步的运行时间比异步还短那么几毫秒。异步反而更慢,异步编程风格并不关乎单纯的速度,而是关乎可扩展性。
|
||||
|
||||
## 模块系统
|
||||
|
||||
模块化是现代软件开发中的一个关键概念。它使我们能够构建更健壮的代码,并在多处复用代码,而无需重复编写相同的代码。
|
||||
|
||||
Node 模块化不仅为我们提供了上述所有好处,还提供了:
|
||||
|
||||
* 自动封装。默认情况下,一个模块中的所有代码都被打包到函数包装程序中,以便对模块外部的其他 JavaScript 代码隐藏。
|
||||
|
||||
* 一种公开模块接口的方式。模块中的函数、变量和其他构造必须通过 module.exports(或者其简短表示:exports)对模块外部的 JavaScript 模块显式公开。
|
||||
|
||||
### 引入模块
|
||||
|
||||
在ES6发布后,module成为标准。曾经的我们采用的是CommonJS规范,使用`require()`来引入模块。目前的ES6标准使用`import`来引入模块。
|
||||
|
||||
```js
|
||||
let fs = require('fs');
|
||||
import fs from 'fs';
|
||||
```
|
||||
|
@ -4,7 +4,7 @@ date: 2019-06-29 12:12:41
|
||||
tags: Tools
|
||||
categories: 实践
|
||||
url: online-ascii-video
|
||||
index_img: /images/ASCII在线视频流/logo.jpg
|
||||
index_img: /images/ASCII在线视频流/logo.webp
|
||||
---
|
||||
|
||||
什么是ASCII?
|
||||
@ -18,7 +18,7 @@ ASCII(American Standard Code for Information Interchange,美国信息交换
|
||||
|
||||
这是来自某位大佬胡乱起的名字。🤣
|
||||
|
||||

|
||||

|
||||
|
||||
## 那么如何安装呢?
|
||||
|
||||
@ -59,7 +59,7 @@ ffmpeg -i demo.mp4 -r 5 -ss 00:01:13 -t 00:00:15 %03d.png
|
||||
将demo视频的第1分13秒后的15秒以每秒5帧的速度保存为图像,图像名格式为001.png 002.png ……
|
||||
效果如下:
|
||||
|
||||

|
||||

|
||||
|
||||
```bash
|
||||
➜ ~ ls time
|
||||
|
@ -4,7 +4,7 @@ date: 2019-06-26 16:42:41
|
||||
tags: typecho
|
||||
categories: 踩坑
|
||||
url: alioss-for-typecho
|
||||
index_img: /images/AliOssForTypecho/logo.jpg
|
||||
index_img: /images/AliOssForTypecho/logo.webp
|
||||
---
|
||||
|
||||
原作大佬:
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Can't install gifsicle
|
||||
index_img: /images/Can't%20install%20gifsicle/index.png
|
||||
index_img: /images/Can't%20install%20gifsicle/index.webp
|
||||
date: 2020-08-04 14:03:00
|
||||
tags: network
|
||||
categories: 踩坑
|
||||
@ -71,7 +71,7 @@ The `Command failed` just write some ips for hosts, then `npm install` will be w
|
||||
|
||||
So,
|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
|
||||
|
@ -4,7 +4,7 @@ date: 2019-12-19 11:11:33
|
||||
tags: Linux
|
||||
categories: 实践
|
||||
url: docker-container-all
|
||||
index_img: /images/Docker全面容器化/logo.png
|
||||
index_img: /images/Docker全面容器化/logo.webp
|
||||
---
|
||||
|
||||
自上篇[Docker - 构建属于自己的镜像](https://www.defectink.com/defect/docker-build-own-images.html)以来,发现Docker非常的有意思。主要是非常的方便,并且在可以跨平台的情况下部署环境对于以后迁移也是一件极其有利的事。研究了Dockerfile的编写以及实践。一些基础的实践之后,对于Docker的工作方式以及操作命令都有了一些熟悉。也逐渐了发现了它的一些优点。
|
||||
@ -72,7 +72,7 @@ apache与php-fpm通信借助Docker的网络,实现内部的通信。
|
||||
|
||||
在Docker hub中的[httpd](https://hub.docker.com/_/httpd)当前支持的tag:
|
||||
|
||||

|
||||

|
||||
|
||||
整个Dockerfile:
|
||||
|
||||
|
@ -4,7 +4,7 @@ date: 2019-11-29 09:30:33
|
||||
tags: Linux
|
||||
categories: 实践
|
||||
url: docker-build-own-image
|
||||
index_img: /images/Docker-构建属于自己的镜像/logo.png
|
||||
index_img: /images/Docker-构建属于自己的镜像/logo.webp
|
||||
---
|
||||
|
||||
以前一直在使用别人构建好的镜像来使用Docker容器,在一次想搭建一个完整的Web环境时,发现使用过多容器非常难以管理。并且容器之间的交互通信变的困难。当然,也可以使用Docker Compose来捆绑多个镜像运行;不过对于运行服务较少的来说,使用Dockerfile来构建成一个镜像也是件好事。
|
||||
|
@ -4,7 +4,7 @@ date: 2019-06-19 15:42:41
|
||||
tags: Linux
|
||||
categories: 实践
|
||||
url: try-the-gitlab
|
||||
index_img: /images/Gitlab尝鲜/52152339.png
|
||||
index_img: /images/Gitlab尝鲜/52152339.webp
|
||||
---
|
||||
|
||||
## Gitlab?
|
||||
@ -17,7 +17,7 @@ index_img: /images/Gitlab尝鲜/52152339.png
|
||||
|
||||
最早,它是完全免费的开源软件,按照 MIT 许可证分发。毕竟人家是公司,后来Gitlab被拆分成GitLab CE(社区版)和 GitLab EE(企业版)。和如今的模式一样,ce是完全免费使用的社区版,而ee是可以进行试用且更多功能的收费版。
|
||||
|
||||

|
||||

|
||||
|
||||
## 安装部署
|
||||
|
||||
@ -25,7 +25,7 @@ index_img: /images/Gitlab尝鲜/52152339.png
|
||||
|
||||
我当前是部署在Ubuntu上的,系统信息:
|
||||
|
||||

|
||||

|
||||
|
||||
官方是推荐系统空闲内存在4GB以上的,对于类似我们这样的个人使用的较少的来说,推荐空闲内存是2GB以上。毕竟它会自己运行一套nginx、redis等服务端。
|
||||
|
||||
@ -71,7 +71,7 @@ sudo EXTERNAL_URL="https://gitlab.example.com" apt-get install gitlab-ce
|
||||
|
||||
## 使用
|
||||
|
||||

|
||||

|
||||
|
||||
简洁多彩的界面也时非常的好看的。默认没有配置邮件的情况下是可以随意注册的,我们也可以在后台配置里关闭自动注册,作为一个私人的git仓库。也可以手动添加用户给想尝鲜的小伙伴们。
|
||||
|
||||
|
@ -4,7 +4,7 @@ date: 2019-12-18 16:42:53
|
||||
tags: HTML
|
||||
categories: 实践
|
||||
url: header-practice-have-to-win-this-a
|
||||
index_img: /images/Header实践-得拿下这个A/header-security.png
|
||||
index_img: /images/Header实践-得拿下这个A/header-security.webp
|
||||
---
|
||||
|
||||
[Header安全检测](https://securityheaders.com/)
|
||||
@ -192,13 +192,13 @@ Feature-Policy: <directive> <allowlist>
|
||||
|
||||
## 测试
|
||||
|
||||

|
||||

|
||||
|
||||
### 为什么没有A+?
|
||||
|
||||
因为CSP的一个报错,拒绝加载内联的JS脚本。可以使用`unsafe-inline`来启用内联脚本。但是启用了`unsafe-inline`之后,就得不到A+了。
|
||||
|
||||

|
||||

|
||||
|
||||
```
|
||||
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-eval' https://maxcdn.bootstrapcdn.com https://ajax.googleapis.com https://cdn.defectink.com". Either the 'unsafe-inline' keyword
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Hexo and Github
|
||||
index_img: /images/Hexo-and-Github/index.png
|
||||
index_img: /images/Hexo-and-Github/index.webp
|
||||
date: 2017-09-14 22:06:12
|
||||
tags: [Linux, HTML]
|
||||
categories: 实践
|
||||
@ -21,9 +21,9 @@ url: hexo-and-github
|
||||
|
||||
在个人资料页面选择仓库(Repositories),并单击New来创建一个新的仓库:
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
• Repository name:仓库名称(需要使用格式为"Your_github_name.github.io"。Your_github_name一定要为你的github昵称,否则出现404状况)
|
||||
• Description:仓库描述(选填)
|
||||
@ -34,7 +34,7 @@ url: hexo-and-github
|
||||
|
||||
随后便能看到自己刚刚创建的仓库了(下图为未创建一个README文件来初始化仓库)
|
||||
|
||||

|
||||

|
||||
|
||||
## 关联Github
|
||||
|
||||
@ -99,11 +99,11 @@ npm install hexo-deployer-git --save
|
||||
|
||||
查看刚刚所部署的仓库
|
||||
|
||||

|
||||

|
||||
|
||||
访问域名测试
|
||||
|
||||

|
||||

|
||||
|
||||
到此就成功部署到Github并运行成功了呢。
|
||||
|
||||
|
414
source/_posts/JavaScript-可迭代对象与for-of.md
Normal file
@ -0,0 +1,414 @@
|
||||
---
|
||||
title: JavaScript-可迭代对象与for-of
|
||||
date: 2020-10-29 17:15:48
|
||||
tags: JavaScript
|
||||
categories: 笔记
|
||||
url: javascript-iterable-object-and-for-of
|
||||
index_img: /images/JavaScript-可迭代对象与for-of/logo.webp
|
||||
---
|
||||
|
||||
## Iterable object(可迭代对象)
|
||||
|
||||
可迭代(Iterable) 对象是数组的泛化。这个概念是说任何对象都可以被定制为可在`for...of`循环中使用的对象。数组是可迭代的。但不仅仅是数组,很多其他的内建对象也是可迭代的。例如字符串就是可迭代的。
|
||||
|
||||
## 总最早开始
|
||||
|
||||
可能十年前或者更加久远的年代,我们遍历一个数组需要这样:
|
||||
|
||||
```js
|
||||
let arr = [1, 2, 3, 4, 5];
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
console.log(arr[i]);
|
||||
}
|
||||
```
|
||||
|
||||
或许也不是很久,在我最初学习js的时候就是这样去尝试理解for循环的。
|
||||
|
||||
后来我们发现这样写或许太复杂了,于是有了`for...in`。我们遍历一个数组就变成了这样:
|
||||
|
||||
```js
|
||||
for (let i in arr) {
|
||||
console.log(arr[i]);
|
||||
}
|
||||
```
|
||||
|
||||
是不是和for循环有点类似,`for...in`便是循环遍历对象的一个方式。
|
||||
|
||||
ES6也给了我们一个专门操作遍历数组的方法:`forEach()`
|
||||
|
||||
```js
|
||||
arr.forEach(element => {
|
||||
console.log(element);
|
||||
});
|
||||
```
|
||||
|
||||
与其他的方法不同的是,`forEach()`同数组的`push()`、`pop()`等方法一样,是在Array对象的原型上的,也就是`Array.prototype.forEach()`。并且它除了抛出异常以外,没有办法中止或跳出`forEach()`循环。如果我们需要中止或跳出循环`forEach()`方法不是应当使用的工具。
|
||||
|
||||
### 弥补不足
|
||||
|
||||
我们有多种可以轻松遍历数组的方法,不过他们各有各的不足之处。`for...of`便是代替`for...in`来循环数组而诞生的。
|
||||
|
||||
首先来看看`for...in`对数组的小问题:
|
||||
|
||||
1. `for...in`是为对象设计的,它遍历的是key,而不是value。
|
||||
2. `for...in`会一直查找可枚举的属性,直至原型链顶端。
|
||||
|
||||
先看第一条,`for...in`和直接for循环遍历数组类似,他们循环的是数组的key,需要使用数组的标准访问写法才能得到值。
|
||||
|
||||
```js
|
||||
let arr = [1, 2, 3, 4, 5];
|
||||
|
||||
for (let i in arr) {
|
||||
console.log(arr[i]);
|
||||
// 1, 2, 3, ,4, 5
|
||||
}
|
||||
|
||||
for (let i in arr) {
|
||||
console.log(i);
|
||||
// 0, 1, 2, 3, ,4
|
||||
}
|
||||
```
|
||||
|
||||
不过这看上去无伤大雅,第二条的问题就不像这么温柔了。在当前数组的原型链上的所有的可枚举的属性都会被遍历出来。
|
||||
|
||||
```js
|
||||
Array.prototype.arrTest = function test() {};
|
||||
|
||||
Object.defineProperty(Array.prototype, 'push', {
|
||||
enumerable: true
|
||||
})
|
||||
|
||||
let arr = [1, 2, 3, 4, 5];
|
||||
|
||||
for (let i in arr) {
|
||||
console.log(arr[i]);
|
||||
}
|
||||
```
|
||||
|
||||
无论是我们自定义的函数,还是修改属性为可枚举,`for...in`一条都不会放过。
|
||||
|
||||

|
||||
|
||||
## 迭代协议
|
||||
|
||||
通常的对象是不可迭代的,它不是数组。通过自己创建一个不可迭代的对象,我们就可以轻松地掌握可迭代的概念。
|
||||
|
||||
首先来看一个最基本的对象,我们尝试使用`for...of`去遍历它,会得到一个其不是可迭代对象的是错误:
|
||||
|
||||
```js
|
||||
let obj = {
|
||||
start: 1,
|
||||
end: 5
|
||||
};
|
||||
|
||||
for (num of obj) {
|
||||
console.log(num);
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
VM155:6 Uncaught TypeError: obj is not iterable
|
||||
```
|
||||
|
||||
这是因为我们的Object对象不是可迭代的对象。而迭代协议可以使其成为一个可迭代的对象。
|
||||
|
||||
迭代协议作为 ECMAScript 2015 的一组补充规范,迭代协议并不是新的内置实现或语法,而是协议。这些协议可以被任何遵循某些约定的对象来实现。
|
||||
|
||||
### 迭代器
|
||||
|
||||
为了让`obj`对象可迭代(也就让`for..of`可以运行)我们需要为对象添加一个名为`Symbol.iterator`的方法(一个专门用于使对象可迭代的内置symbol)。
|
||||
|
||||
1. 当 `for..of` 循环启动时,它会调用这个方法(如果没找到,就会报错)。这个方法必须返回一个 **迭代器(iterator)** —— 一个有 `next` 方法的对象。
|
||||
2. 从此开始,`for..of` **仅适用于这个被返回的对象**。
|
||||
3. 当 `for..of` 循环希望取得下一个数值,它就调用这个对象的 `next()` 方法。
|
||||
4. `next()` 方法返回的结果的格式必须是 `{done: Boolean, value: any}`,当 `done=true` 时,表示迭代结束,否则 `value` 是下一个值。
|
||||
|
||||
```js
|
||||
let obj = {
|
||||
start: 1,
|
||||
end: 5
|
||||
};
|
||||
|
||||
// for..of 调用首先会调用这个:
|
||||
obj[Symbol.iterator] = function () {
|
||||
return {
|
||||
// 这个function还是属于obj,所以this指向obj。
|
||||
//接下来,for..of 仅与此迭代器一起工作,要求它提供下一个值
|
||||
current: this.start,
|
||||
last: this.end,
|
||||
// next() 在 for..of 的每一轮循环迭代中被调用
|
||||
// 所以通常next都带有一个判断语句
|
||||
next() {
|
||||
// Symbol.iterator返回的是一个对象,this不会多级指向,所以这里用到了刚刚定义的属性
|
||||
if (this.current <= this.last) {
|
||||
return {
|
||||
value: this.current++,
|
||||
done: false
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
done: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 可以迭代啦
|
||||
for (let num of obj) {
|
||||
console.log(num);
|
||||
};
|
||||
```
|
||||
|
||||
第一次见到迭代器的时候感觉它还是挺复杂的,但仔细研究过后就会发现,其实它大部分还都是固定搭配的。不过这里的this还是比较容易浑人的。
|
||||
|
||||
仔细观察下其核心的功能,发现迭代器是通过一个名为`Symbol.iterator`的方法返回的对象中的:
|
||||
|
||||
1. `obj` 自身没有 `next()` 方法。
|
||||
2. 相反,是通过调用 `obj[Symbol.iterator]()` 创建了另一个对象,即所谓的“迭代器”对象,并且它的 `next` 会为迭代生成值
|
||||
|
||||
那么,既然都是对象,所以迭代器应该是可以放在`obj`自身的。
|
||||
|
||||
```js
|
||||
let obj = {
|
||||
start: 1,
|
||||
end: 5,
|
||||
// Symbol.iterator负责返回一个对象,其对象中包含next方法,这里直接返回this,在obj中定义一个next方法
|
||||
// this.count用于计数
|
||||
[Symbol.iterator]() {
|
||||
this.count = this.start;
|
||||
return this;
|
||||
},
|
||||
next() {
|
||||
if (this.count <= this.end) {
|
||||
return {
|
||||
value: this.count++,
|
||||
done: false
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
done: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (let num of obj) {
|
||||
console.log(num);
|
||||
};
|
||||
```
|
||||
|
||||
这里的`[Symbol.iterator]()`定义为`obj`的一个属性,同时`[Symbol.iterator]()`需要返回一个带有`next()`方法的对象。所以直接将`next()`方法定义在`obj`身上,`[Symbol.iterator]()`通过返回this来返回这个对象。
|
||||
|
||||
这样的写法会比在外部定义`[Symbol.iterator]()`方法更加简洁,this指向也更加清晰。但是在`[Symbol.iterator]()`方法中定义的属性会被添加到`obj`上。
|
||||
|
||||
```js
|
||||
obj.count // 6
|
||||
```
|
||||
|
||||
并且迭代器只用一个,现在不能在该对象上同时运行多个`for...of`循环了,它们将共享迭代状态,因为只有一个迭代器,即对象本身。但是两个并行的 for..of 是很罕见的,即使在异步情况下。
|
||||
|
||||
> 无穷迭代器
|
||||
> 无穷迭代器也是可能的。例如,将`obj`设置为`obj.to = Infinity`,这时`obj`则成为了无穷迭代器。或者我们可以创建一个可迭代对象,它生成一个无穷伪随机数序列。也是可能的。
|
||||
> `next`没有什么限制,它可以返回越来越多的值,这是正常的。
|
||||
> 当然,迭代这种对象的`for..of`循环将不会停止。但是我们可以通过使用`break`来停止它。
|
||||
|
||||
### 展开语法
|
||||
|
||||
展开语法(Spread syntax), 可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。
|
||||
|
||||
字面量也就是常见的`[1, 2, 3]`或者`{name: "mdn"}`这种简洁的构造方式。
|
||||
|
||||
展开语法与`for...of`及其相似,无法迭代的对象也无法使用展开语法。错误信息也是一样:
|
||||
|
||||

|
||||
|
||||
展开语法不仅仅只是和`for...of`行为比较像,它还有更多的用法。不过在此赘述也是没有多少意义了。
|
||||
|
||||
## 可迭代的字符串
|
||||
|
||||
在我最早学习js的基本类型的时候,就被告知字符串可以被循环处理。类似于这样:
|
||||
|
||||
```js
|
||||
let str = 'xfy';
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
console.log(str[i]);
|
||||
}
|
||||
// x, f, y;
|
||||
```
|
||||
|
||||
虽然无法理解是什么一回事,但当时就感觉字符串和数组很相似,非常神奇。
|
||||
|
||||
根据包装对象的原理,很容易就联想到字符串可迭代是因为其构造函数`String`可迭代(当然也有length属性)。要验证这非常简单,只需要找下`String`上有没有迭代器必备的`[Symbol.iterator]()`方法就可以了。
|
||||
|
||||
虽然包装对象的过程我们无法看到,但是我们可以对一个字符串的原型链向上寻找就ok了。直接调用其原型链上的方法便会触发包装对象,就像调用`toString()`一样,
|
||||
|
||||
```js
|
||||
let str = 'xfy';
|
||||
str.__proto__[Symbol.iterator];
|
||||
```
|
||||
|
||||
直接访问原型链上的`[Symbol.iterator]()`方法,就会发现有这个方法存在,正是有它的存在,字符串才是可迭代的。
|
||||
|
||||
### 显式调用迭代器
|
||||
|
||||
为了能够更加深入的了解迭代器的工作,我们可以不使用`for...of`,反而使用显式的去操作迭代器:
|
||||
|
||||
```js
|
||||
let str = 'xfy';
|
||||
|
||||
// 接收迭代器
|
||||
let iterator = str[Symbol.iterator]();
|
||||
let res;
|
||||
|
||||
while(true) {
|
||||
res = iterator.next();
|
||||
if (res.done) break;
|
||||
console.log(res.value);
|
||||
}
|
||||
```
|
||||
|
||||
只要弄弄清楚了迭代器的工作方式,就能很轻松的理解显式调用。最终我们根据`next()`方法返回的固定格式的值来判断什么适合需要跳出循环以及取值。
|
||||
|
||||
正常情况下我们不需要显式的去迭代一个对象,但是这样做比`for...of`给了我们更多的控制权。我们可以拆分迭代的步骤,并在中途做一些其他的事情。
|
||||
|
||||
## 可迭代与类数组
|
||||
|
||||
可迭代对象与类数组很相似,但他们是两种不同的对象,有着不同的正式术语:
|
||||
|
||||
- **Iterable** 如上所述,是实现了 `Symbol.iterator` 方法的对象。
|
||||
- **Array-like** 是有索引和 `length` 属性的对象,所以它们看起来很像数组。
|
||||
|
||||
当然也有两种特性都有的对象,例如字符串就是可迭代同时也是类数组(有数值索引和 `length` 属性)。
|
||||
|
||||
当光是类数组的对象是无法迭代的
|
||||
|
||||
```js
|
||||
let obj = {
|
||||
0: 'x',
|
||||
1: 'f',
|
||||
2: 'y',
|
||||
length: 3
|
||||
}
|
||||
// Uncaught TypeError: object is not iterable
|
||||
[...obj];
|
||||
```
|
||||
|
||||
可迭代对象和类数组对象通常都**不是数组**,他们也没有数组的一些方法。不过出了字符串以外,我们手动创建的类数组可以使用`call`来改变数组方法的指向,从而使其能够使用一些数组的方法:
|
||||
|
||||
```js
|
||||
Array.prototype.push.call(obj, 1);
|
||||
obj[3];
|
||||
// 1
|
||||
```
|
||||
|
||||
而包装后的字符串其`length`属性是只读的,所以我们无法通过数组的方法去操作它:
|
||||
|
||||
```js
|
||||
let str = 'xfy';
|
||||
// Uncaught TypeError: Cannot assign to read only
|
||||
Array.prototype.push.call(str, 1);
|
||||
```
|
||||
|
||||
### Array.from
|
||||
|
||||
`Array.from`可以从一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。通过创建一个浅拷贝的数组,就可以对其使用数组的方法了。
|
||||
|
||||
```js
|
||||
let obj = {
|
||||
0: 'x',
|
||||
1: 'f',
|
||||
2: 'y',
|
||||
length: 3
|
||||
};
|
||||
|
||||
let arr = Array.from(obj);
|
||||
|
||||
arr.push('嘤嘤嘤');
|
||||
```
|
||||
|
||||
Array.from 方法接受对象,检查它是一个可迭代对象或类数组对象,然后创建一个新数组,并将该对象的所有元素浅拷贝到这个新数组。可迭代的对象也是同理。
|
||||
|
||||
```js
|
||||
let obj = {
|
||||
0: 'x',
|
||||
1: 'f',
|
||||
[Symbol.iterator]() {
|
||||
this.sw = true;
|
||||
return this;
|
||||
},
|
||||
next() {
|
||||
if (this.sw) {
|
||||
this.sw = false;
|
||||
return {
|
||||
value: Object.keys(this),
|
||||
done: false
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
done: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let arr = Array.from(obj);
|
||||
```
|
||||
|
||||
`Array.from`还有一个可选的参数,提供了类似于`forEach`的参数选项。
|
||||
|
||||
```js
|
||||
Array.from(obj[, mapFn, thisArg])
|
||||
```
|
||||
|
||||
可选的第二个参数 `mapFn` 可以是一个函数,该函数会在对象中的元素被添加到数组前,被应用于每个元素,此外 `thisArg` 允许我们为该函数设置 `this`。
|
||||
|
||||
```js
|
||||
Array.from([1, 2, 3], x => x + x);
|
||||
// [2, 4, 6]
|
||||
```
|
||||
|
||||
### 可用于代理对
|
||||
|
||||
对于代理对(surrogate pairs)( UTF-16 的扩展字符),`Array.from`也可以正常识别并拷贝为数组。对于普通的字符串,虽然能够使用`slice()`方法,但是对于代理对的操作会导致乱码,两个不同 UTF-16 扩展字符碎片拼接的结果。
|
||||
|
||||
```js
|
||||
let str = '𝒳😂𩷶';
|
||||
|
||||
console.log(str);
|
||||
// "𝒳😂𩷶"
|
||||
str.slice(1,3)
|
||||
// "<22><>"
|
||||
```
|
||||
|
||||
我们可以利用`Array.from`对代理对的正确操作特性来重写创建代理感知(surrogate-aware)的`slice`方法。
|
||||
|
||||
```js
|
||||
let str = '𝒳😂𩷶';
|
||||
function aSlice(arr, star, end) {
|
||||
return Array.from(arr).slice(star, end).join('');
|
||||
}
|
||||
```
|
||||
|
||||
## 总结
|
||||
|
||||
可以应用 `for..of` 的对象被称为 **可迭代的**。
|
||||
|
||||
- 技术上来说,可迭代对象必须实现 `Symbol.iterator`方法。
|
||||
- `obj[Symbol.iterator]` 的结果被称为 **迭代器(iterator)**。由它处理进一步的迭代过程。
|
||||
- 一个迭代器必须有 `next()` 方法,它返回一个 `{done: Boolean, value: any}` 对象,这里 `done:true` 表明迭代结束,否则 `value` 就是下一个值。
|
||||
- `Symbol.iterator` 方法会被 `for..of` 自动调用,但我们也可以直接调用它。
|
||||
- 展开语法的操作结果与`for..of`类似。
|
||||
- 内置的可迭代对象例如字符串和数组,都实现了 `Symbol.iterator`。
|
||||
- 字符串迭代器能够识别代理对(surrogate pair)。
|
||||
|
||||
有索引属性和 `length` 属性的对象被称为 **类数组对象**。这种对象可能还具有其他属性和方法,但是没有数组的内建方法。
|
||||
|
||||
## 参考&推荐
|
||||
|
||||
* [迭代协议](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols)
|
||||
* [迭代器和生成器](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Iterators_and_Generators)
|
||||
* [yield*](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/yield*)
|
||||
* [展开语法](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_syntax)
|
||||
* [Iterable object(可迭代对象)](https://zh.javascript.info/iterable)
|
@ -4,7 +4,7 @@ date: 2020-07-03 15:13:05
|
||||
tags: JavaScript
|
||||
categories: 笔记
|
||||
url: javascript-scope-and-chain
|
||||
index_img: /images/JavaScript的作用域与链/index.jpg
|
||||
index_img: /images/JavaScript的作用域与链/index.webp
|
||||
---
|
||||
|
||||
JavaScript是一门动态语言,也常称呼为弱类型/解释型的语言。除了不需要明确写出数据类型外,JavaScript的作用域也和其他类型的语言不同。并且作用域还以链的方式互相连接。
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: JavaScript的函数
|
||||
index_img: /images/JavaScript的函数/index.jpg
|
||||
index_img: /images/JavaScript的函数/index.webp
|
||||
date: 2020-08-07 11:26:10
|
||||
tags: JavaScript
|
||||
categories: 笔记
|
||||
|
@ -4,12 +4,12 @@ date: 2020-01-06 09:14:53
|
||||
tags: JavaScript
|
||||
categories: 笔记
|
||||
url: javascript-notes-reference-type
|
||||
index_img: /images/JavaScript笔记-引用类型/javascript.jpg
|
||||
index_img: /images/JavaScript笔记-引用类型/javascript.webp
|
||||
---
|
||||
|
||||
> 这是来自Professional JavaScript for Web Develops第五章的笔记。
|
||||
|
||||

|
||||

|
||||
|
||||
## 基本类型和引用类型
|
||||
|
||||
|
@ -4,7 +4,7 @@ date: 2020-07-27 16:42:32
|
||||
tags: JavaScript
|
||||
categories: 笔记
|
||||
url: javascript-object-oriented-programming
|
||||
index_img: /images/JavaScript面向对象的程序设计/logo.png
|
||||
index_img: /images/JavaScript面向对象的程序设计/logo.webp
|
||||
---
|
||||
|
||||
> Standing on Shoulders of Giants.
|
||||
@ -17,7 +17,7 @@ ECMAScript中没有类的概念,所以它的对象也与基于类的语言中
|
||||
|
||||
ECMAScript-262的对象定义为:“无序属性的集合,其属性可以是基本值、对象和函数。”也就是说对象是一个没有属性的键值映射对,其值可以是数据和函数。
|
||||
|
||||

|
||||

|
||||
|
||||
## 属性类型
|
||||
|
||||
@ -526,7 +526,7 @@ for-in循环会便利所有能访问、可枚举(enumerated)的属性。无论
|
||||
|
||||
这里的two实例重写了`toString()`方法,可以被for-in循环遍历出来。
|
||||
|
||||

|
||||

|
||||
|
||||
若要更方便的取出实例的自有属性,可以使用`Object.keys()`方法。它会返回所有自有的可枚举的属性。返回结果为一个数组,出现顺序与for-in循环相同。
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Node.js之旅
|
||||
index_img: /images/Node.js之旅/2020-09-03-16-16-04.png
|
||||
index_img: /images/Node.js之旅/2020-09-03-16-16-04.webp
|
||||
date: 2020-09-03 16:09:29
|
||||
tags: [JavaScript, Node]
|
||||
categories: 笔记
|
||||
@ -11,7 +11,7 @@ url: get-starting-for-node-js
|
||||
|
||||
Node.js不仅仅是服务器上的JavaScript。
|
||||
|
||||

|
||||

|
||||
|
||||
## 并不熟悉的JavaScript
|
||||
|
||||
|
@ -4,7 +4,7 @@ date: 2019-05-29 16:21:15
|
||||
tags: Network
|
||||
categories: 网络
|
||||
url: basic-knowledge-of-qinq
|
||||
index_img: /images/QinQ基础操作/qinq.jpg
|
||||
index_img: /images/QinQ基础操作/qinq.webp
|
||||
---
|
||||
|
||||
> QwQ♥
|
||||
@ -73,7 +73,7 @@ Tips:Dot1q终结子接口和QinQ终结子接口不支持透传不带VLAN的报
|
||||
|
||||
QinQ报文有着固定的格式,就是在802.1Q的标签上再堆叠一层802.1Q标签。QinQ报文比普通的vlan标签多4个字节。vlan帧最小帧长为68字节。
|
||||
|
||||

|
||||

|
||||
|
||||
| 字段 | 长度 | 含义 |
|
||||
| ------------------- | ----------- | ------------------------------------------------------------ |
|
||||
@ -89,13 +89,13 @@ QinQ报文有着固定的格式,就是在802.1Q的标签上再堆叠一层802.
|
||||
|
||||
### 报文示例
|
||||
|
||||

|
||||

|
||||
|
||||
### TPID(Tag Protocol Identifier)
|
||||
|
||||
TPID:标签协议标识ID(Tag Protocol Identifier)是Vlan tag中的一个字段,标识该vlan tag的协议类型。IEEE 802.1Q协议规定QinQ的外层vlan标签的type值为:(0x8100)。
|
||||
|
||||

|
||||

|
||||
|
||||
> IEEE802.1Q协议定义的以太网帧的VLAN Tag。802.1Q Tag位于SA(Source Address)和Length/Type之间。通过检查对应的TPID值,设备可确定收到的帧承载的是运营商VLAN标记还是用户VLAN标记。接收到帧之后,设备将配置的TPID值与帧中TPID字段的值进行比较。如果二者匹配,则该帧承载的是对应的VLAN标记。例如,如果帧承载TPID值为0x8100的VLAN标记,而用户网络VLAN标记的TPID值配置为0x8200,设备将认为该帧没有用户VLAN标记。也就是说,设备认为该帧是Untagged报文。
|
||||
> 另外,不同运营商的系统可能将QinQ帧外层VLAN标记的TPID设置为不同值。为实现与这些系统的兼容性,可以修改TPID值,使QinQ帧发送到公网时,承载与特定运营商相同的TPID值,从而实现与该运营商设备之间的互操作性。以太网帧的TPID与不带VLAN标记的帧的协议类型字段位置相同。为避免在网络中转发和处理数据包时出现问题,不可将TPID值设置为下表中的任意值:
|
||||
@ -118,7 +118,7 @@ TPID:标签协议标识ID(Tag Protocol Identifier)是Vlan tag中的一个
|
||||
|
||||
拓扑:
|
||||
|
||||

|
||||

|
||||
|
||||
如图示,SW2和SW3用于模拟运营商之间的Internet,SW1和SW4为客户内网。基本QinQ的配置就作用于SW2和SW3之间,将客户内网内的vlan10与vlan20封装上一层vlan100,用于再SW2和SW3之间传输。
|
||||
|
||||
@ -164,7 +164,7 @@ SW1的`G 0/0/1`为trunk接口,对应连接的SW2的`G 0/0/1`为基本二层Qin
|
||||
|
||||
使用PC1发送ICMP包到PC3,数据包内容为:
|
||||
|
||||

|
||||

|
||||
|
||||
其中,可以看到内层的802.1q的vlan标签ID为10,type为(0x0800);外层的,也就是SW2封装的vlan标签ID为100,type为(0x8100)。
|
||||
|
||||
@ -172,7 +172,7 @@ SW1的`G 0/0/1`为trunk接口,对应连接的SW2的`G 0/0/1`为基本二层Qin
|
||||
|
||||
拓扑和上述一样:
|
||||
|
||||

|
||||

|
||||
|
||||
我们在模拟internet的SW2和SW3之间添加了一个vlan 200,用于配置灵活的QinQ的vlan 20堆叠一个vlan 200的tag。
|
||||
|
||||
@ -201,11 +201,11 @@ interface GigabitEthernet0/0/2
|
||||
|
||||
* vlan10
|
||||
|
||||

|
||||

|
||||
|
||||
* vlan20
|
||||
|
||||

|
||||

|
||||
当两台PC机正常通信的时候,可以看到不同vlan封装的外层vlan tag也是不一样的。这就是基于vlan的灵活QinQ。
|
||||
|
||||
## 上述拓扑
|
||||
|
@ -4,7 +4,7 @@ date: 2019-05-18 12:31:45
|
||||
tags: Tools
|
||||
categories: 实践
|
||||
url: multi-platform-real-time-synchronization-by-resilio-sync
|
||||
index_img: /images/Resilio-Sync多平台实时同步/res.png
|
||||
index_img: /images/Resilio-Sync多平台实时同步/res.webp
|
||||
---
|
||||
|
||||
> 备份,同步一步到位。🏹
|
||||
@ -74,16 +74,16 @@ Windows是我们平常接触最多的一款GUI操作系统了,对于安装软
|
||||
|
||||
安装界面仅仅只需要一步
|
||||
|
||||

|
||||

|
||||
合适的选择后,对于较新的Windows平台可是直接打开一个软件窗口
|
||||
|
||||

|
||||

|
||||
|
||||
接受了几个隐私政策与EULA之后(有空还是要多留意条款之类的),我们就可以正常使用了。
|
||||
|
||||
打开后的简洁的界面
|
||||
|
||||

|
||||

|
||||
|
||||
配置之类的稍后再说,再将自己的其他平台的机器也给完成安装。
|
||||
|
||||
@ -310,7 +310,7 @@ root 29385 0.3 0.4 589864 9676 ? Ssl 15:43 0:00 /usr/bin/rslsyn
|
||||
|
||||
成后运行后的界面与Windows完全一样。毕竟二者是同一种方式展示的UI界面。
|
||||
|
||||

|
||||

|
||||
|
||||
## 同步
|
||||
|
||||
@ -318,19 +318,19 @@ root 29385 0.3 0.4 589864 9676 ? Ssl 15:43 0:00 /usr/bin/rslsyn
|
||||
|
||||
在保证权限都是正常的情况下,添加在A机器添加我们需要进行同步的文件夹。选择好了之后就是三种分享链接的方式。
|
||||
|
||||

|
||||

|
||||
|
||||
分别是“链接”、“密钥”和二维码三种方式。
|
||||
|
||||
随后我们就可以使用三种方式的其中一种,例如使用我最喜欢的密钥,选择好读写权限后,在需要同步的B机器上输入复制过来的密钥。
|
||||
|
||||

|
||||

|
||||
|
||||
然后等着他们自己开始同步就OK了。在多平台的环境下也是不会影响正常工作的。
|
||||
|
||||
除此之外,对于同步的文件夹还有一些其他的选项可以配置。具体就看自己的需要来配置了🌭
|
||||
|
||||

|
||||

|
||||
|
||||
## 参考&推荐阅读
|
||||
|
||||
|
@ -11,7 +11,7 @@ index_img: /images/Teamspeak-Server/logo.jpg
|
||||
|
||||
## Teamspeak?
|
||||
|
||||

|
||||

|
||||
|
||||
Teamspeak是一套专有的VoIP软件。所谓VoIP软件,就是基于网络协议的语音通话。而Teamspeak就是和现在市面上大多数即时通讯软件差不多,可以发送即时消息以及多人语音通话。
|
||||
|
||||
@ -219,7 +219,7 @@ firewall-cmd --reload
|
||||
前面有介绍过TS使用的是C/S架构,我们搭建好了服务端当然是为了连接它。连接它比我们想象的要简单的多,打开软件后直接在工具栏就能找到连接这一选项。
|
||||
单击连接,就可以根据服务器地来连接我们搭建好的服务端了。
|
||||
|
||||

|
||||

|
||||
|
||||
我们可以看到有三个选项框,第一个是服务器地址,其次是服务器密码,最后是用于展示给其他人的昵称
|
||||
默认新安装的服务端是没有密码的,如果我们是连接一个新服务器的话,是可以将密码留空登陆。
|
||||
@ -233,20 +233,20 @@ firewall-cmd --reload
|
||||
|
||||
如果是第一次连接至ts的新服务器,那么我们连接成功后就会立马弹出一个用于输入token的对话框。我们将刚刚创建服务器时给我们的token填入即可。这样就可以直接在客户端修改自己的服务器了。
|
||||
|
||||

|
||||

|
||||
|
||||
因为ts默认在使用客户端时会自动创建一个用户身份,每个身份都是不相同的。**那如果我们更换电脑连接自己的服务器时,或者想给其他人一个修改服务器的权限时该怎么办呢?**
|
||||
|
||||
- 导出当前的用户身份
|
||||
|
||||
在工具栏的“工具-身份”这个标签中,我们可以看到自己当前账户身份。直接右击便可以执行导出操作。在其他地方使用相同方法导入就可以继续使用这个身份了。
|
||||

|
||||

|
||||
|
||||
- 新建token码
|
||||
|
||||
当我们想给其他身份的用户修改服务器的权限的时候,我们可以使用新建权限码的方式来提升其他用户的权限。
|
||||
在工具栏的“权限-权限码清单”中就可以找的新建权限码的按钮以及已经新建过的权限码清单。新建时也可以选择不同的权限来进一步控制。使用权限码就和我们第一次使用时一样操作即可。
|
||||

|
||||

|
||||
|
||||
### 翻译插件
|
||||
|
||||
@ -254,16 +254,16 @@ firewall-cmd --reload
|
||||
|
||||
打开软件后,打开“工具-选项”(Alt+P),找到“插件(add-ons)”这一选项卡。
|
||||
|
||||

|
||||

|
||||
|
||||
默认看到的是当前本地的插件,我们可以选择“Browse online"来查看在线可以下载安装的插件。选择筛选器为”翻译“然后输入”Chinese“就可以找到一款繁体中文的插件。点击进入插件的详情页面就可以看到”install“。单击安装即可。
|
||||
|
||||

|
||||

|
||||
|
||||
Install完成之后重新打开软件就会应用上翻译了。如果没有成功应用,可以再去刚刚插件地方看看有没有启用。
|
||||
除了翻译插件之外,TS还有很多种类的插件,以及界面皮肤等。和刚刚安装翻译插件的方法一摸一样。
|
||||
|
||||

|
||||

|
||||
|
||||
## 参考
|
||||
|
||||
|
@ -4,7 +4,7 @@ date: 2020-10-22 11:21:22
|
||||
tags: [JavaScript, Vue]
|
||||
categories: 笔记
|
||||
url: Vue-js-get-started
|
||||
index_img: /images/Vue.js-起步!/logo.png
|
||||
index_img: /images/Vue.js-起步!/logo.webp
|
||||
---
|
||||
|
||||
在我打算学习vue的时候,正是其3.0版本发布不久的时候。很庆幸生活在这个时代,但困扰我的是是否应该由旧版本的2.x开始学习?一向选择困难的我最终打算两个版本一起学习,从2.x开始入门,顺便还能一睹其与3.0版本的变化。
|
||||
@ -182,7 +182,7 @@ Vue还提供了`v-model`指令,它能够轻松实现对表单的双向绑定
|
||||
|
||||
组件系统是Vue的另一个重要概念,它是一种抽象,允许我们使用小型、独立和通常可复用的组件构建大型应用。一个大型的页面应用将由几个可重复利用的组件构成。
|
||||
|
||||

|
||||

|
||||
|
||||
在 Vue 里,一个组件本质上是一个拥有预定义选项的一个 Vue 实例。在 Vue 中注册组件很简单:
|
||||
|
||||
@ -473,4 +473,4 @@ Vue同样也暴露了一些内建的属性,例如`$attrs`和`$emit`。他们
|
||||
|
||||
下图可以很清晰的看到Vue3的实例的一个生命周期。
|
||||
|
||||

|
||||

|
@ -3,7 +3,7 @@ title: Hello World
|
||||
tags:
|
||||
date: 1999-06-05 17:42:58
|
||||
url: hello-world
|
||||
index_img: /images/hello-world/index.jpg
|
||||
index_img: /images/hello-world/index.webp
|
||||
---
|
||||
Welcome to [Hexo](https://hexo.io/)! This is your very first post. Check [documentation](https://hexo.io/docs/) for more info. If you get any problems when using Hexo, you can find the answer in [troubleshooting](https://hexo.io/docs/troubleshooting.html) or you can ask me on [GitHub](https://github.com/hexojs/hexo/issues).
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: hexo
|
||||
index_img: /images/hexo/index.png
|
||||
index_img: /images/hexo/index.webp
|
||||
date: 2017-08-30 11:08:19
|
||||
tags: [Linux, HTML]
|
||||
categories: 实践
|
||||
@ -70,7 +70,7 @@ $ npm install
|
||||
hexo init web
|
||||
```
|
||||
|
||||

|
||||

|
||||
|
||||
过程略长,稍等即可
|
||||
|
||||
@ -119,7 +119,7 @@ hexo server -p 80 -s
|
||||
|
||||
正常情况下便可以直接进行访问,为如下页面。
|
||||
|
||||

|
||||

|
||||
|
||||
Cannot GET / ?
|
||||
|
||||
|
@ -4,7 +4,7 @@ date: 2019-05-16 14:21:37
|
||||
tags: Minecraft
|
||||
categories: 实践
|
||||
url: minecraft-bedrock-server
|
||||
index_img: /images/Minecraft-bedrock服务端/217940907.jpg
|
||||
index_img: /images/Minecraft-bedrock服务端/217940907.webp
|
||||
---
|
||||
|
||||
## Minecraft
|
||||
|
@ -4,7 +4,7 @@ date: 2019-06-14 14:42:41
|
||||
tags: Linux
|
||||
categories: Linux
|
||||
url: basic-knowledge-of-systemd
|
||||
index_img: /images/systemd的基础操作/logo.png
|
||||
index_img: /images/systemd的基础操作/logo.webp
|
||||
---
|
||||
|
||||
## 什么是systemd?
|
||||
|
@ -13,7 +13,7 @@ emoji是我们身边常见的且神奇的表情符号,它被称为绘文字(
|
||||
|
||||
Emoji的编码是Unicode字符集中的一部分,特定形象的Emoji表情符号对应到特定的Unicode字节。也就是说emoji是unicode编码。好处是无论在什么地方使用都不像是图片那么难处理,以及可以直接写在数据库内。
|
||||
|
||||
![emoji_unicode.png][1]
|
||||
![emoji_unicode.webp][1]
|
||||
|
||||
### 词语发音
|
||||
|
||||
@ -29,7 +29,7 @@ Emoji的编码是Unicode字符集中的一部分,特定形象的Emoji表情符
|
||||
|
||||
现在多数的软件、网站等都已经广泛的支持emoji表情了。自己也是非常的喜欢这类表情,特别喜欢微软家的,那种扁平的风格真的很招人喜爱。
|
||||
|
||||
![1557663679707.png][2]
|
||||
![1557663679707.webp][2]
|
||||
|
||||
但是最近使用typecho的时候遇到点小问题,发现新安装的typecho居然不支持使用emoji。在文章等页面使用了emoji之后,保存会提示数据库查询错误。
|
||||
|
||||
@ -53,7 +53,7 @@ alter table typecho_users convert to character set utf8mb4 collate utf8mb4_unico
|
||||
|
||||
修改后就可以看到表的‘排序规则’(charset)为可以使用emoji的`utf8mb4`了。
|
||||
|
||||
![2019-05-12T12:27:33.png][3]
|
||||
![2019-05-12T12:27:33.webp][3]
|
||||
|
||||
### 修改typecho配置文件
|
||||
|
||||
@ -72,11 +72,11 @@ $db->addServer(array (
|
||||
|
||||
全部修改完成后就能正常的在typecho中使用emoji了
|
||||
|
||||
![2019-05-12T12:31:18.png][4]
|
||||
![2019-05-12T12:31:18.webp][4]
|
||||
|
||||
|
||||
|
||||
[1]: ../images/使typecho支持emoji/2721696195.png
|
||||
[2]: ../images/使typecho支持emoji/1431864746.png
|
||||
[3]: ../images/使typecho支持emoji/175217384.png
|
||||
[4]: ../images/使typecho支持emoji/4188132525.png
|
||||
[1]: ../images/使typecho支持emoji/2721696195.webp
|
||||
[2]: ../images/使typecho支持emoji/1431864746.webp
|
||||
[3]: ../images/使typecho支持emoji/175217384.webp
|
||||
[4]: ../images/使typecho支持emoji/4188132525.webp
|
@ -4,7 +4,7 @@ date: 2019-11-18 12:53:53
|
||||
tags: Windows
|
||||
categories: 踩坑
|
||||
url: modify-icloud-storage-location-on-windows
|
||||
index_img: /images/修改Windows端iCloud云盘存储位置/logo.jpeg
|
||||
index_img: /images/修改Windows端iCloud云盘存储位置/logo.webp
|
||||
---
|
||||
|
||||
|
||||
@ -30,11 +30,11 @@ C:\WINDOWS\system32>mklink /D C:\Users\Defectink\iCloudDrive D:\iCloudDrive
|
||||
|
||||
没有退出按钮?
|
||||
|
||||

|
||||

|
||||
|
||||
> 如果先退出再复制文件可能会导致意外
|
||||
|
||||

|
||||

|
||||
|
||||
## 启动文件夹
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
title: 入坑IRC
|
||||
index_img: /images/入坑IRC/logo.png
|
||||
index_img: /images/入坑IRC/logo.webp
|
||||
date: 2020-08-22 18:37:36
|
||||
tags: [tools,IRC,Linux]
|
||||
categories: 日常
|
||||
@ -43,7 +43,7 @@ IRC并不像现代的聊天软件一样,需要先注册账号才能使用。
|
||||
|
||||
输入注册命令后就会收到认证的邮件,邮件大概是这样的(freenode):
|
||||
|
||||

|
||||

|
||||
|
||||
将邮件里的内容再输入一遍就注册完成了。
|
||||
|
||||
@ -75,7 +75,7 @@ IRC并不像现代的聊天软件一样,需要先注册账号才能使用。
|
||||
4. Select `SASL (username + password)` for the `Login method` field
|
||||
5. In the `Password` field, enter your NickServ password
|
||||
|
||||

|
||||

|
||||
|
||||
## 频道
|
||||
|
||||
|
@ -4,7 +4,7 @@ date: 2019-06-05 18:51:32
|
||||
tags: Linux
|
||||
categories: 实践
|
||||
url: public-key-cryptgraphy
|
||||
index_img: /images/公开密钥密码学/logo.jpeg
|
||||
index_img: /images/公开密钥密码学/logo.webp
|
||||
---
|
||||
|
||||
GPG/PGP赛高!
|
||||
@ -60,7 +60,7 @@ GPG/PGP赛高!
|
||||
|
||||
既然上述已经介绍了它是自由软件,那么它跨平台的几率就很大了,支持的平台也非常的多。在官方网站里,我们可以看到它支持很多平台。
|
||||
|
||||

|
||||

|
||||
|
||||
#### Windows GPG4win
|
||||
|
||||
@ -70,9 +70,9 @@ GPG/PGP赛高!
|
||||
|
||||
GPG4win是GPG在Windows平台的一款可视化的非对称加密软件。对于可视化的软件来说,使用也非常的简单明了。 几乎常用的一些功能都非常直白的写在了刚开打的页面中。基本上只要使用者了解大概的非对称加密的运作原理,就可以很轻松的使用该软件了。
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
#### Ubuntu & CentOS
|
||||
|
||||
|
@ -4,7 +4,7 @@ date: 2020-06-29 12:12:41
|
||||
tags: Tools
|
||||
categories: 实践
|
||||
url: write-and-cooperation
|
||||
index_img: /images/写作与协作/index.png
|
||||
index_img: /images/写作与协作/index.webp
|
||||
---
|
||||
|
||||
出于对速度无理的追求,最终还是放弃了使用动态内容。转战静态blog。以前也稍微尝试过hexo,所以决定还是主要为hexo为主了。
|
||||
@ -51,7 +51,7 @@ Hexo的仓库直接push,之后CI持续集成就会按照预设好的步骤来
|
||||
|
||||
除了外观从清新脱俗到繁重了一点,余下就只剩方便了。对于我这种才转到hexo的写作半吊子,一直很想找个与hexo契合度高的写作姿势。之前需要在Typora中写完,然后再将文章和单独的图片文件夹复制到hexo的`souce/_post`目录。像我这种半年产出一篇文章的还好,要是天天写,那样会被麻烦死。况且,如果有某一篇文章出了点小差错需要改。那就要同时动两个md文件和两组图片文件夹,对着资源管理翻来覆去的找,极为麻烦!🌚
|
||||
|
||||

|
||||

|
||||
|
||||
#### 粘贴图片🖼
|
||||
|
||||
@ -104,7 +104,7 @@ Editor > Suggest: Snippets Prevent Quick Suggestions
|
||||
|
||||
使用CI持续部署的好处就是,可以完全专心与创作,而不用再去管部署之类的问题。只需要第一次写好流程,剩下的就全部交给自动化吧。
|
||||
|
||||

|
||||

|
||||
|
||||
之前的我从来没有用过Coding,对CI/CD也没有什么了解,从来没考虑过自动化部署这类操作。后来在研究静态化网站时发现了新大陆,完全可以将复杂重复的工作交给机器。并且随着后面文章的增加,渲染markdown文件肯定会越来越慢,于其手动繁琐的操作,不如完全交给CI。
|
||||
|
||||
@ -112,7 +112,7 @@ Editor > Suggest: Snippets Prevent Quick Suggestions
|
||||
|
||||
在我研究CI姿势的这段时间里,Github也推出了自己的CI(钞能力)。无论是谁家的CI,除了部署步骤不一样,其结果肯定是相同的。Github action也是能达到同样的效果,对于各个厂家的云存储,action也有同样的解决方法,甚至是比coding的jenkins还要灵活一点。
|
||||
|
||||

|
||||

|
||||
|
||||
## Hexo插件📥
|
||||
|
||||
@ -160,7 +160,7 @@ image_minifier:
|
||||
interlaced: false
|
||||
multipass: false
|
||||
optimizationLevel: 2
|
||||
pngquant: false
|
||||
webpquant: false
|
||||
progressive: false
|
||||
silent: false
|
||||
```
|
||||
@ -191,7 +191,7 @@ feed:
|
||||
content_limit: 140
|
||||
content_limit_delim: ' '
|
||||
order_by: -date
|
||||
icon: icon.png
|
||||
icon: icon.webp
|
||||
autodiscovery: true
|
||||
template:
|
||||
|
||||
@ -312,7 +312,7 @@ sudo gdebi your_ossfs_package
|
||||
|
||||
成功了安装了之后就可以配置oss的账号信息来登陆。使用AccessKeyId/AccessKeySecret来代替账号密码进行访问。如果担心安全问题还可以使用阿里云的子账号只赋予oss的访问权限,来最大程度的保护账户资产。在阿里云的[RAM访问控制](https://ram.console.aliyun.com/overview)中可以进行添加子账户并赋予特定的权限。
|
||||
|
||||

|
||||

|
||||
|
||||
AccessKeyId/AccessKeySecret信息存放在`/etc/passwd-ossfs`文件中。并且文件的权限必须正确设置,建议设为640。
|
||||
|
||||
@ -365,5 +365,5 @@ ossfs#bucket_name mount_point fuse _netdev,url=url,allow_other 0 0
|
||||
|
||||
并且阿里云也早就支持了子目录首页了。只需要简单开一下就能解决这个问题。
|
||||
|
||||

|
||||

|
||||
|
||||
|
@ -4,7 +4,7 @@ date: 2018-06-29 12:12:41
|
||||
tags: [Linux, HTML]
|
||||
categories: 实践
|
||||
url: hexo-again
|
||||
index_img: /images/想起来当年还折腾过hexo/index.png
|
||||
index_img: /images/想起来当年还折腾过hexo/index.webp
|
||||
---
|
||||
|
||||
## Hexo
|
||||
@ -314,6 +314,6 @@ defect.ink
|
||||
记录的虽然不是太多,也可能不是那么详细。但是还是大致的顺着搭建成功这么一个放向来的的。
|
||||
所以就留下一个截图的纪念吧?
|
||||
|
||||

|
||||

|
||||
|
||||
~~图丢了~~
|
@ -4,7 +4,7 @@ date: 2019-06-28 12:12:41
|
||||
tags: Tools
|
||||
categories: 踩坑
|
||||
url: bark-custom-notification-for-apple
|
||||
index_img: /images/水果自定义通知大法/logo.jpg
|
||||
index_img: /images/水果自定义通知大法/logo.webp
|
||||
---
|
||||
|
||||
> ding~
|
||||
@ -23,7 +23,7 @@ App Store中有位大佬开发的[Bark](https://apps.apple.com/cn/app/bark-给
|
||||
|
||||
Github:[Bark](https://github.com/Finb/Bark)
|
||||
|
||||

|
||||

|
||||
|
||||
默认它提供了自己的服务器,如果我们需要推送一些较为隐私的消息,可以使用自建服务端。它提供了http接口,后端简单调用即可给自己的水果设备发送推送。
|
||||
|
||||
@ -107,7 +107,7 @@ RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
|
||||
|
||||
如果一切都没啥问题的话,我们直接打开刚刚配置好证书的apache站点,bark应该就是能够正常运行了。
|
||||
|
||||

|
||||

|
||||
|
||||
## Systemd
|
||||
|
||||
@ -135,4 +135,4 @@ WantedBy=multi-user.target
|
||||
|
||||
具体的效果就和平时使用其他的systemd控制的软件一样了,并且不用再那么麻烦了。
|
||||
|
||||

|
||||

|
@ -4,7 +4,7 @@ date: 2019-06-05 16:41:57
|
||||
tags: Linux
|
||||
categories: Linux
|
||||
url: auto-backup
|
||||
index_img: /images/自动备份大法/bakcup.jpg
|
||||
index_img: /images/自动备份大法/bakcup.webp
|
||||
---
|
||||
|
||||
## 引入
|
||||
@ -13,7 +13,7 @@ index_img: /images/自动备份大法/bakcup.jpg
|
||||
|
||||
因为一个lsyncd的日志写了34GB。
|
||||
|
||||

|
||||

|
||||
|
||||
## 操作
|
||||
|
||||
@ -113,7 +113,7 @@ find /root/backup/tar.gz/sql -mtime +3 -name "*.*" -exec rm -rf {} \;
|
||||
|
||||
先来简单的介绍下可爱的crontab文件的时间格式吧。
|
||||
|
||||

|
||||

|
||||
|
||||
星号(*):代表所有可能的值,例如month字段如果是星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。
|
||||
|
||||
|
@ -4,7 +4,7 @@ date: 2019-05-29 9:05:01
|
||||
tags: Linux
|
||||
categories: 踩坑
|
||||
url: fixed-inotify-watch-not-enough
|
||||
index_img: /images/解决inotify-watch不够/logo.jpg
|
||||
index_img: /images/解决inotify-watch不够/logo.webp
|
||||
---
|
||||
|
||||
> Failed to add /run/systemd/ask-password to directory watch: No space left on device
|
||||
|
@ -144,4 +144,34 @@ background: linear-gradient(to bottom,transparent 60%,rgba(189,202,219,.3) 0) no
|
||||
.markdown-body h1, .markdown-body h2 {
|
||||
padding-bottom: .3em;
|
||||
border-bottom: 0px solid #eaecef !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 浪漫雅园!! */
|
||||
/* @font-face {
|
||||
font-family: "LMYY";
|
||||
src: url("https://cdn.defectink.com/static/fonts/yayuan.woff")
|
||||
}
|
||||
* {
|
||||
font-family: "LMYY" !important;
|
||||
} */
|
||||
/* 代码块里的字太小 */
|
||||
/* .markdown-body pre code {
|
||||
font-size: 100% !important;
|
||||
} */
|
||||
|
||||
/* 滚动条,webkit赛高! */
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
background-color: transparent;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: darkgray;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.v[data-class=v] .vwrap .vedit {
|
||||
position: relative;
|
||||
padding-top: 10px;
|
||||
background: no-repeat right bottom url(https://cdn.defectink.com/static/images/iloli.gif);
|
||||
background-size: 20%;
|
||||
}
|
Before Width: | Height: | Size: 20 KiB |
BIN
source/images/ASCII在线视频流/logo.webp
Normal file
After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 410 KiB |
BIN
source/images/ASCII在线视频流/图像-1.webp
Normal file
After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 152 KiB |
BIN
source/images/ASCII在线视频流/图像-2.webp
Normal file
After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 56 KiB |
BIN
source/images/AliOssForTypecho/logo.webp
Normal file
After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 91 KiB |
BIN
source/images/Can't install gifsicle/index.webp
Normal file
After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 106 KiB |
BIN
source/images/Can't install gifsicle/批注 2020-08-04 135700.webp
Normal file
After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 10 KiB |
BIN
source/images/Docker-构建属于自己的镜像/logo.webp
Normal file
After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 25 KiB |
BIN
source/images/Docker全面容器化/image-20191221185631177.webp
Normal file
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 838 B |
BIN
source/images/Docker全面容器化/logo.webp
Normal file
After Width: | Height: | Size: 936 B |
Before Width: | Height: | Size: 23 KiB |
BIN
source/images/Gitlab尝鲜/411390967.webp
Normal file
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 42 KiB |
BIN
source/images/Gitlab尝鲜/52152339.webp
Normal file
After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 35 KiB |
BIN
source/images/Gitlab尝鲜/99634888.webp
Normal file
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 9.6 KiB |
BIN
source/images/Header实践-得拿下这个A/header-security.webp
Normal file
After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 53 KiB |
BIN
source/images/Header实践-得拿下这个A/image-20191218171928050.webp
Normal file
After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 28 KiB |
BIN
source/images/Header实践-得拿下这个A/image-20191218172218399.webp
Normal file
After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 45 KiB |
BIN
source/images/Hexo-and-Github/create.webp
Normal file
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 63 KiB |
BIN
source/images/Hexo-and-Github/ggg.webp
Normal file
After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 81 KiB |
BIN
source/images/Hexo-and-Github/index.webp
Normal file
After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 9.7 KiB |
BIN
source/images/Hexo-and-Github/profile.webp
Normal file
After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 11 KiB |
BIN
source/images/Hexo-and-Github/repository.webp
Normal file
After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 387 KiB |
BIN
source/images/Hexo-and-Github/web.webp
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
source/images/JavaScript-可迭代对象与for-of/2020-10-27-15-01-39.webp
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
source/images/JavaScript-可迭代对象与for-of/2020-10-29-10-17-49.webp
Normal file
After Width: | Height: | Size: 8.1 KiB |
BIN
source/images/JavaScript-可迭代对象与for-of/logo.webp
Normal file
After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 46 KiB |
BIN
source/images/JavaScript的作用域与链/index.webp
Normal file
After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 37 KiB |
BIN
source/images/JavaScript的作用域与链/scope.webp
Normal file
After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 65 KiB |
BIN
source/images/JavaScript的函数/index.webp
Normal file
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 53 KiB |
BIN
source/images/JavaScript笔记-引用类型/javascript.webp
Normal file
After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 13 KiB |
BIN
source/images/JavaScript面向对象的程序设计/image-20200726171729248.webp
Normal file
After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 15 KiB |
BIN
source/images/JavaScript面向对象的程序设计/logo.webp
Normal file
After Width: | Height: | Size: 10 KiB |