js相关(杂七杂八)

箭头函数

(1)更简洁的语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function functionName (params) {
return statement;
}
箭头函数:
(params) => {statement};
当参数只有一个时,可以写成:
params => {statement};
当没有参数时:
() => {statement};
当返回的函数是一个运算表达式时,可以简化为:
params => statement;
1
2
var double = num => num * 2;
double(2); // 4

(2)箭头函数中的this

箭头函数的this和调用时的上下文无关。而是在定义的时候就决定了,根据词法作用域来确定this的指向:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function taskA() {
this.name = 'hello'
var fn = function() {
console.log(this) // window
console.log(this.name) // hello
}
var arrow_fn = () => {
console.log(this) // window
console.log(this.name) // hello
}
fn()
arrow_fn()
}
taskA()

虽然普通函数fu的输出和箭头函数arrow_fn的输出相同,但是他们的this的确定方式却不同。

fu是在运行时产生的,由于我们直接调用的fu,所以它的this就指向window

arrow_fn是根据词法作用域产生,与调用的位置无关。由于他自身没有this,于是便向外面一层查找this,这时在taskA中找到了this,于是直接继承了taskA的作用域。taskA是一个普通函数,所以它的this由调用的位置决定,所以,this指向window

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function taskA() {
this.name = 'hello'
var fn = function() {
console.log(this)
console.log(this.name)
}
var arrow_fn = () => {
console.log(this);
console.log(this.name)
}
var obj = {
name: 'haha',
fn: fn,
arrow_fn: arrow_fn
}
obj.fn(); // obj haha
obj.arrow_fn(); // window hello
}
taskA()

其他案例:

箭头函数:

1
2
3
4
5
6
7
var obj = {
field: 'hello',
getField: () => {
console.log(this.field)
}
}
obj.getField() // undefined

根据词法作用域,getField中的this指向全局,由于全局中没有field这个属性,所以返回undefined

普通函数:

1
2
3
4
5
6
7
8
var obj = {
field: 'hello',
getField() {
console.log(this.field)
}
}
obj.getField(); // hello

普通函数的this由运行的位置决定。

(3)箭头函数中的arguments

箭头函数不暴露arguments对象,所以你没办法在箭头函数中使用arguments.length操作。在箭头函数中使用arguments指向的是其外层函数的arguments对象。

如果一定要用arguments,可以试试剩余参数:

1
2
3
4
5
6
function foo() {
var fn = (...args) => args[0]; // ...剩余参数会将args转换为一个数组
return fn(2);
}
foo(1);

(4)箭头函数不能被当做构造函数

也就是箭头函数不能用:

1
var fn = new (a => a); // TypeError

由于http是无状态协议,所以为了跟踪用户会话,就引入了cookie,用于存储用户的登录信息。

cookie存在客户端,session存在服务器端。

cookie在与服务器端通信每次都会携带在HTTP头中。

cookie的默认生命周期为浏览器关闭就随之消失,你也可以自己设置一个生存期。

cookie的缺点:

(1)大小和数目受限制,服务器规定了一个域中cookie的数目。同时限制了每一个cookie的大小,不能超过4k。

(2)存在安全性问题,容易被人拦截。

(3)需要指定域,不能跨域。

(4)有些浏览器不支持cookie或者会禁用cookie。

(5)浪费带宽,每次请求都会携带在HTTP中发送出去。

cookie、localStorage、sessionStorage的区别

localstrorage

本地存储,用于存放一些数据在浏览器。

特性:

大小为5M,相比cookie来说,大得多。

持久化存储,不会过期,除非手动删除。

存在于客户端,不会发送到服务端,不参与服务器通信,减少了http请求次数。

sessionStorage

本地存储,用于存储临时数据,浏览器关闭数据就清空。其他用法和localStorage一样。

cookie、session、token的区别

(1)session用于验证用户的身份, 服务器为了区分用户的身份就给每一个客户端分配了不同的session ID。这个session ID存储在cookie中。用户离开网站时这个session会被销毁。

(2)token用于身份验证,由三部分组成,用户id + 生成时间 + sign。存在cookie中。

(3)cookie数据存放在浏览器上,session数据存放在服务器上。

callapplybind的区别

(1)三者都可用于改变this的指向,都可以利用后续参数传参;

(2)callapply会立即执行,而bind返回的是一个函数,不会立即执行,要调用才会执行;

(3)对于传参,他们的第一个参数都是this要指向的对象,但后续参数不同。call接受的是连续参数,apply接受的是数组参数。当参数数目不确定时建议使用apply。而对于bind它有两种参数传入方式:

1
2
3
a.bind(b, 'c', 'd')();
a.bind(b)('c', 'd');

xss和csrf防御

xss的原理

跨站脚本攻击,采用某些手段,经恶意代码植入浏览器的页面代码中,从而对用户客户端实施攻击(代码注入)。

因为是对浏览器进行攻击,所以植入的代码多为html和javascript。

xss危害

(1)窃取浏览器中的cookie;

(2)劫持流量实现恶意跳转。

xss攻击分类

(1)反射型xss

诱骗用户点击攻击的url,经过服务器响应后不加过滤,直接返回给前端。

为非持久性攻击,即攻击相对于访问者是一次性的。

(2)存储型xss

含有xss代码的输入被存储到数据库或存储文件上。当其他用户查看这段文本时,就会运行xss代码。

为持久型攻击。

xss防范

(1)对外部输入进行敏感过滤;(由前端和后台合力完成)

(2)在显示的时候对敏感代码进行处理,不让他执行。(由前端单独完成)

csrf原理

跨站请求伪造,挟持用户在已登录的web界面上执行非本意的操作。

通常来说,csrf是由xss来实现的。

csrf防范

(1)验证码,第三方无法获取到验证码,所以无法完成请求。

(2)token

原理都是导致请求失败。

两者的区别

xss主要是想办法获取该网站的cookie,就可以以别人的身份登录网站。

csrf主要是在用户登录后挟持用于做一些非本意的操作。