cookie、localStorage、sessionStorage区别
Cookie
Cookie设计初衷是用来和服务器通讯,而不是本地存储,他只是被‘借用’到本地存储。
如下图,每次http请求,header都携带cookie;
localStorage、sessionStorage
在HTML5中,新加入了一个localStorage/sessionStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),localStorage中一般浏览器支持的是5M大小。
localStorage、sessionStorage与cookie相比:
localStorage、sessionStorage不同点:
localStorage、sessionStorage API有哪些
localStorage只支持string类型的存储。
var storage=window.localStorage;
//写入a字段
storage["a"]=1;
//写入b字段
storage.a=1;
//写入c字段
storage.setItem("c",3);
//获取a
storage.getItem('a');
storege.a;
storage["a"]
console.log(typeof storage["a"]);// string
storage.clear();//删除所有
storage.removeItem("a");//删除某个
//使用key()方法,向其中出入索引即可获取对应的键
for(var i=0;i<storage.length;i++){
var key=storage.key(i);
console.log(key);
}
//将JSON存入localStorage中,使用JSON.stringify()这个方法,来将JSON转换成为JSON字符串
var data={
name:'xiecanyong',
sex:'man',
hobby:'program'
};
var d=JSON.stringify(data)
storage.setItem("data",d);
//将JSON字符串转换成为JSON对象输出
var json=storage.getItem("data");
var jsonObj=JSON.parse(json);
sessionStorage操作同上
===================================================================
JavaScript中let、const、var 的区别
目录
1.是否存在变量提升?
2.是否存在暂时性死区?
3.是否允许重复声明变量?
4.是否存在块级作用域?
5. 是否能修改声明的变量?
在ES5
中,声明变量只有var
和function
两种形式。但是因为var
声明的变量会有一定的缺点(内层变量可能覆盖外层变量的问题以及用来计数的循环变量泄露为全局变量,下面有介绍),ES6
提出了使用let
和const
声明变量,弥补了ES5
中var
的缺点。
1.是否存在变量提升?
-
var
声明的变量存在变量提升(将变量提升到当前作用域的顶部)。即变量可以在声明之前调用,值为undefined
。 -
let
和const
不存在变量提升。即它们所声明的变量一定要在声明后使用,否则报ReferenceError
错。
console.log(f) //undefined
var f = 1 ;
console.log(g) //ReferenceError: g is not defined
let g = 2;
console.log(h) //ReferenceError: g is not defined
const h = 2;
2.是否存在暂时性死区?
let和const存在暂时性死区
。即只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
var tmp = 123;
if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
/*以上代码if后面{}形成了块级作用域,由于使用let声明了tmp,则这个变量就绑定了
块区域,在声明之前使用,会报错。*/
在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。
总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
3.是否允许重复声明变量?
var f = 4;
var f = 5;
console.log(5) //5
let g = 6;
let g = 7;
console.log(7) //SyntaxError: Identifier 'g' has already been declared
const h = 8;
const h = 9;
console.log(h) //SyntaxError: Identifier 'g' has already been declared
4.是否存在块级作用域?
什么是块级作用域:
ES5中作用域有:全局作用域、函数作用域。没有块作用域的概念。因此也有一系列的问题。
//1,内层变量可能覆盖外层变量的问题
var a = 2;
function fun(){
console.log(a) //undefined
if(false){
var a = 3;//变量提升带来的,尽管存在块级作用域,但是var声明的变量会跨越这个域。
}
}
fun()
//2,用来计数的循环变量泄露为全局变量。
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]);
}
console.log(i); // 5 i循环结束后,泄露成了全局变量
ECMAScript 6(简称ES6)中新增了块级作用域。块作用域由{ }
包括,if
语句和for
语句里面的{ }
也属于块作用域。
//1,解决内层变量可能覆盖外层变量的问题
var b = 2;
function fun1(){
console.log(b) //2 访问的外层变量
if(false){
let b = 3;//不存在变量提升,变量存在于块级作用域之中。
}
}
fun1()
//2,解决用来计数的循环变量泄露为全局变量。
var s1 = 'hello';
for (let j = 0; j < s1.length; j++) {
console.log(s1[j]); //j存在于块级作用域之中,和其绑定
}
console.log(j); // 报错 j is not defined
5. 是否能修改声明的变量?
const f = 10;
// f= 11;
// console.log(f) //报错 不能进行重复声明
const obj = {
name: '小明',
age: 18
}
obj.age = 20
console.log(obj) //{ name: '小明', age: 20 }
//const声明常量,不允许对变量重新赋值。对于引用类型的值而言,只要在栈内存保存的地址值不变即可。
===================================================================
es6解构赋值
定义:
解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。
语法:
//数组结构
var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20
//对象解构
({
a, b } = {
a: 10, b: 20 });
console.log(a); // 10
console.log(b); // 20
// ...rest 解构数组
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]
// ...rest 解构对象(最新)
({
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}
//解析一个从函数返回
function f() {
return [1, 2];
}
var a, b;
[a, b] = f();
console.log(a); // 1
console.log(b); // 2
更多应用场景
1、默认值
var a, b;
[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7
2、交换变量
var a = 1;
var b = 3;
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
3、忽略你不感兴趣的返回值
function f() {
return [1, 2, 3];
}
var [a, , b] = f();
console.log(a); // 1
console.log(b); // 3
4、将剩余数组赋值给一个变量
当解构一个数组时,可以使用剩余模式,将数组剩余部分赋值给一个变量。
var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
5、给新的变量名赋值
可以从一个对象中提取变量并赋值给和对象属性名不同的新的变量名。
var o = {
p: 42, q: true};
var {
p: foo, q: bar} = o;
console.log(foo); // 42
console.log(bar); // true
6、For of 迭代和解构
var people = [
{
name: 'Mike Smith',
family: {
mother: 'Jane Smith',
father: 'Harry Smith',
sister: 'Samantha Smith'
},
age: 35
},
{
name: 'Tom Jones',
family: {
mother: 'Norah Jones',
father: 'Richard Jones',
brother: 'Howard Jones'
},
age: 25
}
];
for (var {
name: n, family: {
father: f}} of people) {
console.log('Name: ' + n + ', Father: ' + f);
}
// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"