JS & Rx.js & HTTP

函数

this&call……

1
2
3
4
5
6
function a() {
console.log(this)
console.log(arguments)
}
a.call() // 隐式传入this, arguments
a() // 隐式传入arguments,实际为window.a()

a()是a.call()的阉割版本, this是对象与函数之间的桥, this永远指向call的第一个参数

1
2
3
4
5
6
7
8
9
10
11
12
13
let a = {
b: 1,
c(val) {
console.log(val.b)
},
d() {
console.log(this.b)
}
}
a.c.call(a) // 1
a.d // 1
// 以A为this调用c或d
// this是.前面的东西,为空则为window

当call的arguments为数组时,使用apply

1
2
3
4
5
6
7
8
9
10
11
12
13
let view = {
el: $('##div1'),
bindEvents() {
this.el.onclick = this.onClick.bind(this)
this.el.onclick = function() {
this.onClick.call(this)
}
// 两者相等
},
onClick() {
this.el.addClass('active')
}
}

this指向问题

1
2
3
4
function a(val) {
console.log(val)
}
a(1) // 不运行则不知道传的值
  1. 参数的值在传值时确定
  2. this为call的第一个参数,同时也是任何函数的参数
  3. 同理:this的值只有在传值时确定
  4. 框架中文档的所写的this指向,都可以被call改变,所以都不确定

柯里化

惰性求值

1
2
3
4
5
6
7
function sum(x) {
return function(y) {
return x+y
}
}
let sum1 = sum(1) // x=1
sum1(2) // y=2; 3

构造函数

1
2
3
4
5
function a() {
this.name='none'
}
let fnOne = a.call({})
let fnTwo = new a

箭头函数

因为本身没有this,所以内部的this会向外查找,于是内部this自动指向外部
并且无arguments,所以call不影响箭头函数,以及去掉了坑爹的this

Promise

内部隐式调用失败return Primise.reject()

new

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function a() {
let obj = {
b: 1,
c() {
console.log(1)
},
}
return obj
}

function a1() {
this.b = 1
this.c = function() {
console.log(1)
}
}
new a
new a1

如果构造函数没有参数,那么可以省略括号

Rx.js

源码

1
2
3
4
5
6
7
8
9
Array.prototype.reduce = function(fn, init) {
let result = init
for(let i=0; i<this.length; i++) {
if(i in this) {
result = fn.call(undefined, result, this[i], i, this)
}
}
return result
}

map

1
2
3
4
5
6
arr = arr.map(v => v+1)
// 等同于
arr = arr.reduce((result, v) => {
result.push(v+1)
return result
}, [])

filter

1
2
3
4
5
6
7
8
arr = arr.filter((v => v%2 === 0))

arr = arr.reduce((result, v) => {
if (v%2===0) {
result.push(v)
}
return result
}, [])

展示评分最高的剧集给用户

1
2
3
4
5
6
7
8
9
let getTopRatedFilms = user => {
user.videoLists
.map(videoList=>
videoList.videos
.filter(video => video.rating === '5.0')
).concatAll()
}

getTopRatedFilms(currentUser).forEach(film => console.log(film))

拖拽事件

1
2
3
4
5
6
7
8
9
let getElementDrags = el =>
el.mouseDowns
.map(mouseDown =>
document.mouseMoves
.takeUntil(document.mouseUps) // 丢弃松开按键后的移动
).concatAll()

getElementDrags(div)
.forEach(position => img.position = position)

搜索建议

1
2
3
4
5
6
7
8
9
10
11
12
13
let search = 
keyPresses
.debounce(250) // 等待时间
.map(key =>
getJSON('/search?q=' + input.value)
.retry(3) // 请求失败重新尝试
.takeUntil(keyPresses) // 结束事件
)
.concatAll()
search.forEach(
results => updateUI(results),
error => showMessage(error)
)

优化

表结构

当if else 太多用表结构清晰易懂

1
2
3
4
5
6
7
8
9
10
11
let t ={
true: {
true: 1,
false: 2
},
false: {
true: 3,
false: 4
}
}
t[a][b] // a,b为条件判断,进入到表中某一个结构

哨兵优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let arr = [1, 2, 3, 4, 5]
let search = 5
for (let i=0; i<arr.length; i++) {
if (arr[i] === search) {
return true // 查找存不存在
}
}
// 改进

arr.push(search)
let i = 0
while(i !== arr[i]) {
i++
}
if (i < arr.length) {
// 存在
} else {
// 不存在
}

运算

  • 加减法比乘除快很多
  • N进制左移一位等于乘以N

HTTP

请求 & 响应

  1. Content-Type: application/x-www-form-urlencoded

    • x: 表示非规范协议,为自定义的协议
    • www: 万维网
    • form: 表单形式
    • urlencoded: 被encoded的数据
  2. Content-Type说明提交的数据类型

  3. GET请求一般没有Content-Type
  4. 几种类型
    • text/css; charset=utf-8
    • application/javascript; charset=utf-8
    • text/html; charset=utf-8
    • application/json; charset=utf-8
    • application/javascript; charset=utf-8

优化

  1. Cache-Control: max-age=3600 缓存3600秒
  2. 改文件名使缓存失效
  3. 百度缓存时间 315360000 十年
  4. 入口文件不加缓存
  5. Etag 和 304 请求服务器,但不下载,可以避免下载过程,也不是缓存
    • Etag: aaa
    • 第一次响应返回,第二次请求时会在头部带上
    • If-None-Match: aaa
    • 方便服务器读
    • 304告诉浏览器文件没有更新,不需要读

Cookie和Session区别

  • cookie

    • 区分用户
    • 存在浏览器
  • session

    • 存敏感数据
    • 存在服务器内存、文件、数据库等

反向代理

正向代理代理浏览器,反向代理代理服务器。
客户端1 || 客户端2 -> 未批嗯代理 -> server -> 反向代理 -> server1 || server2