下面的内容仅供自身参考、学习而已,部分内容从 mdn、阮一峰的 《ES6标注入门》等内容摘取。
HTML
META 的作用
通常我们的 html 会定义好 charset
,声明该文件的编码类型。现在应该都是用 utf-8
。
<meta charset="utf-8">
http-equiv
这个枚举属性定义了能改变服务器和用户引擎行为的编译
// 3 秒后,自动刷新。不过这样会一直刷新。。。
<meta http-equiv="refresh" content='3'>
// 也可以做重定向的作用
<meta http-equiv="refresh" content='3;http://www.baidu.com'>
seo 相关的
通过定义 meta ,可以让搜索引擎更容易找到你的网站
<meta name='author' content='xxx'>
<meta name='description' content='xxx'>
<meta name='keywords' content='xxx'>
viewport
主要用于移动端,设置浏览器视口的一些属性
<meta name="viewport" content="width=device-width, initial-scale=1">
- width: 以pixels(像素)为单位, 定义viewport(视口)的宽度
- height: 以pixels(像素)为单位, 定义viewport(视口)的高度
- initial-scale: 定义设备宽度(纵向模式下的设备宽度或横向模式下的设备高度)与视口大小之间的缩放比率
- maximum-scale: 定义设备最大的缩放值,必须要大于或等于
minimum-scale
- minimum-scale: 定义设备最小的缩放值,必须小于或等于
maximum-scale
- user-scalable: 用户是否可以缩放页面
如何区分物理像素、CSS 像素
CSS
换行
单行换行:
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
多行换行:
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
width: 200px;
多行换行只支持 webkit
的浏览器,兼容性不理想。
还有一种纯 css
的方案:
// 三行
.test3 p {
position:relative;
line-height:1.4em;
height:4.2em;
overflow:hidden;
}
p::after {
content:"...";
font-weight:bold;
position:absolute;
bottom:0;
right:0;
padding:0 20px 1px 45px;
background:url(http://newimg88.b0.upaiyun.com/newimg88/2014/09/ellipsis_bg.png) repeat-y;
}
计算 height
的高度,通过 overflow: hidden
和最后的一张图片,对文字进行隐藏。
兼容性很好,但是最后一行的文字如果没有超过一行,那就回造成 …
和文字进行分离
使用 js 进行解决
clamp.js,使用这个库,可以对字符串进行裁剪,达到省略的效果,min 版本,3kb 而已。而且如果浏览器支持上面 css3 的多行省略方法,会直接使用,省去 js 操作。
transition
通过改变样式,产生一个动效。兼容性,ie10 以上,移动端大部分都支持。
/* property name | duration | timing function | delay */
transition: margin-right 4s ease-in-out 1s;
/* Apply to 2 properties */
transition: margin-right 4s, color 1s;
基础的四个属性:
- name — 样式名
- duration — 效果时间
- timing function — 速度变化效果
- delay — 延迟多少秒才开始
可以一次写多个样式,也可以直接全部: all
而且可以使用 js 监控动画是否结束
el.addEventListener("transitionend", updateTransition, true)
每个样式的动画结束后,会触发这个回调。如果中途对 dom 变更样式,并不会触发回调,只有等某个样式的动画停止,才会触发对应样式的回调。
animation
实现一个动画效果,和 transition
类似,但是每个 animation
是事先定义好的,动画也能重复播放,可控制、可实现的效果会更多。
兼容性是支持 ie10,移动端大部分都支持。
属性:
- duration — 动画时间
- timing-function — 速度变化效果
- delay — 延迟多少秒才开始
- iteration-count — 运行次数
- direction — 动画方向
- fill-mode — 动画结束,取决于用哪一帧的样式
- play-state — 定义动画是否运行或暂停
- name — 动画要实现的动画帧名
这里说几个不常用的
direction
- normal — 从第一帧开始
- alternate — 从上一次动画结束的帧开始
- reverse — 从最后帧开始
- alternate-reverse — 第一次从最后帧开始,然后每次从上一次动画结束的帧开始
fill-mode
- none — 保持原样
- forwards — 保持动画结束的最后一针的状态
- backwards — 保持动画开始第一帧状态
- both — 执行 forwards 和 backwards 的动作(没搞懂...)
play-state
- running — 动画在运行
- paused — 动画以结束,如果一开始定义了 paused,动画就不会运行,而且会报错动画最后的状态
keyframes
定义动画帧
@keyframes animation {
from { // ... }
50% { // ... }
to { // ... }
}
动画事件
animation.addEventListener("animationstart", listener, false)
animation.addEventListener("animationend", listener, false)
animation.addEventListener("animationiteration", listener, false)
根据 event.type
判断是什么事件类型
使用 animation
可以省去很多麻烦,配合 js 进行添加 animation
的 class
,大部分普通的效果都可以实现。
transform
可以改变 dom 的位置、旋转、缩放、倾斜,改变的部分,脱离文档流,不会产生重排。
兼容性,2d 效果兼容 ie9,3d 效果兼容 ie10 。移动端大部分浏览器都支持。
这里简单列出属性:
- translate(x, y)
- scale(x, y)
- skew(x, y)
- rotate
- rotate3d(x, y, z, deg)
- matrix()
- matrix3d()
- perspective(1px)
translate, scale, skew 都支持 3d 效果
还有其他有关 transform 的属性:
- transform-origin: (x, y)
- transform-style: 3d
translate、scale、skew、rotate 这些都是很普通的变化。用 translate 和 scale 替代 width、height、top、left 这些属性来操作 dom,会得到动画流畅度更好得表现。
perspective
参考 css_transform 文件,可以看到具体的效果。
JS
路由原理
hash 模式
通过锚点 #
进行跳转,虽然浏览器的 url 是变化了,但是页面没有刷新的。然后可以通过 window.onhashchange
回调判断 url 是否有变化。回调的事件对象,有 oldURL
和 newURL
两个字段,可以用来判断是前进还是后退
history 模式
和 hash 模式类似,不过浏览器有提供 history 对象,有更多的属性和方法,而且 url 会更清晰。通过 window.onpopstate
监听路由 url 的变化。使用 pushState
和 replaceState
对路由进行变化,这两个方法不会导致页面刷新而使 url 进行变化。其中 window.history
还提供其他便捷的方法,例如 go
、back
等。vue-router
中也有其中的方法。而 hash
模式可以通过编写对应的逻辑从而实现。
es6
let 和 const 的特征和区别
特征
以下的 let
共指 let
和`const
不会造成变量提升
如果使用 var
会造成变量提升,对项目后续的调试、维护造成不便
(() => {
console.log(a) // undefined
var a = 1
console.log(a) // 1
})()
而使用 let
/const
不会有这样问题
(() => {
console.log(a) // uncaught ReferenceError
let a = 1
console.log(a)
})()
在同一个代码块内,如果在 let
前获取、赋值对应的变量,会报语法错误。而这又是另外一个特性:暂时性死区。
暂时性死区
// es6标注入门示例代码
var tmp = 123
if (true) {
tmp = 234 // referenceError
let tmp = 345
}
在块作用域内(或函数)某个变量使用了 let
声明,在声明之前任何调用了该变量,都会报错,无论任何情况。
不允许重复声明
(() => {
let a = 1
var a = 2 // Uncaught SyntaxError: Identifier 'a' has already been declared
console.log(a)
})()
像上面代码。
let 与 const 的区别
其他大部分都是一致的。const
命令会保证变量名指向的内存地址不变,但不会保证内存地址内的数据不变。所以 const
声明的变量,是不能改变指向的内存地址,也就是说不能二次赋值。不过对于 object
类型的数据,可以对其子级的属性进行修改,数组也是。
MODULE
在 es6 的 import
和 export
之前,就有了 commonjs
、amd
和 cmd
等模块化方案。commonjs
是 nodejs
的一个常用的方案,而 amd
和 cmd
是在浏览器使用的方案,这两者需要 requirejs
和 seajs
库。也就是说上面三种方案都不是官方标准。
import
的方案是完全静态的,import
前面都不能带有任何的 js 逻辑。
优点是:对比 commonjs
效率会更高,可以实现静态化分析
而 commonjs
可以根据逻辑,需要的时候再引入。
使用
// 基本使用
// test.js
const data = []
export default data
// use
import data from './test'
export:
export const test = 1
export const test2 = 2
// or
export { test, test2 }
//重名
cocnst test3 = 3
export {
test3 as test3_1
}
import
import { test, test2 } from './test
import { test as test_1 } from './test'
// 可以一次加载全部
import * as testAll from './test
循环引用问题
如果几个模块之间循环引用,会造成部分引用的,显示 undefined 问题,在 nodejs 上,会把引用的文件,生成一个空间,但是是 undefied 的。
不同的模块化方案之间的区别
闭包
查看“面试问题”
位运算
位运算是直接对二进制位进行计算。优点处理速度快。JS 数值是以 64 位浮点数存储,位运算是以 32 为带符号整数运算。
& (与运算)
都是 1 的话返回 1,否则返回 0
// 1的二进制表示为: 00000000 00000000 00000000 00000001
// 3的二进制表示为: 00000000 00000000 00000000 00000011
// --
// 返回: 00000000 00000000 00000000 00000001
1 & 3 // 1
| (或运算)
如果有一个是 1,则返回 1,否则返回 0
// 1的二进制表示为: 00000000 00000000 00000000 00000001
// 3的二进制表示为: 00000000 00000000 00000000 00000011
// --
// 返回: 00000000 00000000 00000000 00000011
1 | 3 // 3
^ (异或运算)
有且仅有一个 1 则返回 1,否则返回 0
// 1的二进制表示为: 00000000 00000000 00000000 00000001
// 3的二进制表示为: 00000000 00000000 00000000 00000011
// --
// 返回: 00000000 00000000 00000000 00000010
1 ^ 3 // 2
~ (非运算)
1 变 0, 0 变 1,也就是求二进制的反码
// 1的二进制表示为: 00000000 00000000 00000000 00000001
// -----------------------------
// 1反码二进制表示: 11111111 11111111 11111111 11111110
// 由于第一位(符号位)是1,所以这个数是一个负数。JavaScript 内部采用补码形式表示负数,即需要将这个数减去1,再取一次反,然后加上负号,才能得到这个负数对应的10进制值。
// -----------------------------
// 1的反码减1: 11111111 11111111 11111111 11111101
// 反码取反: 00000000 00000000 00000000 00000010
// 表示为10进制加负号:-2
~ 1 // -2
<< (左移)
将二进制数往右前进一位,舍弃高位(最左边),补低位 0(最右边加 0)
// 1的二进制表示为: 00000000 00000000 00000000 00000001
// -----------------------------
// 2的二进制表示为: 00000000 00000000 00000000 00000010
console.log(1 << 1) // 2
console.log(1 << 2) // 将 1 的二进制,移动两位,得出 4
>> (右移)
将二进制数往右前进一位,舍弃低位(最右边),高位拷贝进行补位
// 1的二进制表示为: 00000000 00000000 00000000 00000001
// -----------------------------
// 0的二进制表示为: 00000000 00000000 00000000 00000000
console.log(1 >> 1) // 0
console.log(1 >> 2) // 将 1 的二进制,移动两位,得出 0
内存泄露
不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。
JS 有自己的垃圾回收机制,自动的内存管理,使用的是“引用计数”。当一个值没有被引用,就会被回收,否则一直存在内存中。
- 要注意全局方法里引用的对象,像 setInterval、dom 的添加事件的回调函数,要使用专门的销毁方法,clearInterval、removeEventListener 这些方法。
- 使用第三方库的时候,有些需要生成实例的,当不需要用到的时候,比如页面卸载,要把这个实例也给销毁掉
冒泡机制
当我们点击一个 div 的时候,正常会从 body 到该 div 的方向,一层层往下触发回调(如果有声明回调事件);直到点击的目标 div;这个过程是捕获阶段;然后会再从该节点一层次往上冒泡,直到 body,这个过程是冒泡阶段
2现代浏览器可以通过 event.stopPropogation() 进行禁止冒泡;而 ie8 之前的 ie 浏览器,可以通过它自身的方法禁止冒泡
websocket
websocket 类似于 http 请求那样,与后台建立起一条数据通信的渠道,但 websocket 是可以让服务器主动发送数据给客户端,而 http 请求却不行。
websocket 要 ie11 才兼容。
// mdn 实例
// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// Listen for messages
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});
// send message to server
socket.send()
// close socket
socket.close()
websocket 可以使用字符串、二进制等数据类型进行通信。
JSON.stringify 的局限性
const a = { a: '123', b: 12, c: [], d: {}, e: function() {}, f: /sdf/, g: undefined, h: null, i: NaN, m: Infinity, n: (Symbol('sdf'))}
console.log(JSON.stringify(a))
// {"a":"123","b":12,"c":[],"d":{},"f":{},"h":null,"i":null,"m":null}
正则类型会转为 {}
undefined
, null
, NaN
都会转为 `null
function
, Infinity
, Symbol
会直接丢失
如何实现 apply call bind
Function.prototype.call = function(ctx, ...args) {
const _ctx = ctx || window
const tempKey = `TEMP_${Date.now()}`
_ctx[tempKey] = this
const res = _ctx[tempKey](...args)
delete _ctx[tempKey]
return res
}
Function.prototype.apply = function(ctx, args) {
const _ctx = ctx || window
const tempKey = `TEMP_${Date.now()}`
_ctx[tempKey] = this
const res = _ctx[tempKey](args)
delete _ctx[tempKey]
return res
}
Function.prototype.bind = function(ctx, ...args) {
const _ctx = ctx || window
const tempKey = `TEMP_${Date.now()}`
_ctx[tempKey] = this
return function(...args2) {
const res = _ctx[tempKey](...args, ...args2)
delete _ctx[tempKey]
return res
}
}
后端
cookie
cookie 是存放在浏览器的一种数据,可由前端或者后端对 cookie 进行增删改查。每个域名下的网页 cookie 大小大概是 4kb 左右,过多的 cookie 会影响页面打开的速度。因为 http 是无状态的,所以 cookie 可以让 http 记录状态信息。
参数
服务器设置 cookie:
Set-Cookie: <cookie名>=<cookie值>
服务器设置 cookie 后,客户端后续的 http 请求,都会带上设置的 cookie,直到过期。
如果不设置 Expires
或者 max-age
,当浏览器关闭后, cookie
会自动删除,这是会话期Cookie
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
设置了 Expires
或者 max-age
就是持久性Cookie
当Cookie的过期时间被设定时,设定的日期和时间只与客户端相关,而不是服务端。
Set-Cookie: id=a3fWa; Secure; HttpOnly; Domain=xxxx.com; Path=/list
Secure
声明该 Cookie
只在 HTTPS 协议带上
HttpOnly
,客户端 js ,Document.cookie
的 api
是无法修改 Cookie
Domain
声明哪些域名可以接受 Cookie
(好像不能多个?)
Path
声明哪些路径可以匹配到,对应的子路径也会匹配到
SESSION
session
是存放在服务器的状态信息,可以存放在文件、内存等。是为了解决 http
无状态问题。比如,当用户发送了登录的请求,服务器验证登录成功后,会把用户的一些数据存放在 session
上,然后会有一个对应此用户的 session_id
,最后一个 session_id
会保存在 cookie
上,携带给客户端。后面每次客户端发送 http
请求,都会带上这个 session_id
,让服务器知道是哪个用户来请求。
用于服务器记录用户状态时,标识具体用户的机制。
session
的操作,就是一套用户 token
的验证,只不过这些代码都帮你写好了,可以直接进行对 session
的增删改查操作
cookie 和 session 的区别
cookie
存放在客户端, 时效性根据用户设置,可短可长;存放大小 4kb 左右;同源的 http 请求都会被带上
session
通常存放在服务器;是服务器实现的一种关联用户状态的存储方式
数据库
MYSQL
以下内容,摘自网上教程和 mysql 参考手册
基础操作
// 登录:
mysql -u root -p
// 查询数据库
show databases;
// 使用数据库
use database_name;
// 查询表
show tables;
// 查看当前数据库状态
status;
// 修改密码
// 5.7.6 之后的版本
ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass';
// 5.7.5 之前的版本
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('MyNewPass');
创建数据库
// 创建数据库
CREATE DATABASE database_name;
// 使用 utf-8 编码
CREATE DATABASE menagerie DEFAULT CHARSET utf8 COLLATE utf8_general_ci;
创建表
// 建表
CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
/*
* 下面是一个建表的代码,这里来解析下一些字段的作用
* 在字段里添加 AUTO_INCREMENT ,代表这个字段会自增长
* -> 后面还有一个 AUTO_INCREMENT = 1000039 的,代表从这个数目开始自增长
* NOT NULL 不允许为空
* DEFAULT '' 默认值为 ''
* CURRENT_TIMESTAMP 当前时间的时间戳,类似的还有 NOW()
* PRIMARY KEY 设置主键
* UNIQUE KEY 起约束作用,保持此字段数据是唯一的
*/
CREATE TABLE `users` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`username` varchar(15) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`password` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`phone` char(11) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
`email` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
`avatar` varchar(200) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
`PHONE` (`phone`),
UNIQUE KEY `EMAIL` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=1000000039 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户';
特殊语句
- WHERE;
WHERE id = 1
条件语句 - AND, OR; 和、或
- LIKE;
%
表示任意语句;WHERE id = 100%
-> id 等于 前三个是100,后面任意字符串的值 - ORDER BY; 排序;
ORDER BY id ASC
,id 升序排序;ORDER BY id DESC
降序 - GROUP BY; 对结果进行分组,可以使用
COUNT, SUM, AVG
这三个函数;SELECT title, COUNT(*) FROM todos GROUP BY title;
参考链接:
CURD
create
// 插入数据,字符串要用引号
INSERT INTO table_name (name, age, year) VALUES ('123', 17, '2018');
update
// 更新数据
UPDATE table_name SET name = 'test2' WHERE id = 1;
read
// 查询数据,查询所有字段
SELECT * FROM table_name
// 查询某字段
SELECT name, age FROM table_name
delete
// 删除数据
DELETE FROM table_name WHERE id = 1
安全
XSS
跨站脚本攻击(Cross Site Scripting),将恶意代码注入到页面中。XSS 攻击,通常会获取客户端 cookie 或其他用户的信息,从而假冒用户进行交互。
大概有两种类型:
- 存储型,通过表单把攻击代码存放在服务器,然后在页面显示出来。
- 反射型,不会存到服务器的,经过用户交互点击攻击,比如点击一个链接
我用 express
生成一个项目,里面用的模板是 jade
如果不用 jade
输出,直接 render.send()
var express = require('express');
var router = express.Router();
const data = `</div><script>console.log(document.cookie)</script>`
router.get('/', function(req, res, next) {
res.send(data)
})
打开页面,就会在控制打印出当前域名的 cookie
然后使用模板渲染
router.get('/', function(req, res, next) {
res.render('index', {
title: 'Express',
test: data
})
})
打开页面,会显示出 </div><script>console.log(document.cookie)</script>
的字符串,console
也没有出现任何的信息
没有被处理过
CSRF
CSRF(Cross-site request forgery),跨站请求伪造
利用你的 cookie,去发起请求,进行攻击。
比如,当你在 a 网站登录后,会产生一个 cookie
,然后在该 cookie
还没有失效或不存在的情况下,访问 b 网站,b 网站会发起一个请求到 a 网站,
基础
AST
抽象語法樹(Abstract Syntax Tree,AST),将代码转为一种树状结构。方便对代码进行增删改查
进程
是 CPU、内存分配的基本单位,是程序执行的一个实例
线程
线程是操作系统,运算调度的最小单位。一个进程里,可以有多个线程
线程之间共享它们的进程所拥有的资源
线程可以并发执行
进程和线程的区别
原码、反码、补码
1 的原码:00000001
1 的反码:00000001
1 的补码:00000001
-1 的原码:10000001
-1 的反码:11111110
-1 的补码:11111111
原码:就是值的二进制的值
反码:正数的反码是其本身。负数的反码,符号位不变,其余位取反
补码:正数的补码是其本身。负数的补码,符号位不变,其余位取反,再 + 1
各类名词术语
erp
Enterprise Resource Planning . ERP是一套面向企业流程管理的系统
ERP是面向工作流的,强调对企业管理的事前控制能力,把财务、制造管理、销售管理、物流管理、库存管理、采购管理和人力资源等方面的作业
wms
Warehouse Management System,是对物料存放空间进行管理的软件,区别于库存管理
其功能主要有两方面,一为通过在系统中设定一定的仓库仓位结构对物料具体空间位置的定位,二为通过在系统中设定一些策略对物料入库\出库\库内等作业流程进行指导
oms
Order Management System的缩写,即订单管理系统
crm
Customer Relationship Management,它是以客户数据的管理为核心,可帮助你保持客户的联系信息处于最新状态
srm
供应商管理系统,供应商关系管理系统SRM是面向供应链前端,用来改善主机厂与其供应链上游供应商关系的系统