js基础问题
1、 promise里面如果直接return了?
链接上来: https://juejin.im/post/5e58c618e51d4526ed66b5cf
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
.then 或者 .catch 的参数期望是函数,传入非函数则会发生值穿透。
第一个then和第二个then中传入的都不是函数,一个是数字类型,一个是对象类型,因此发生了穿透,将resolve(1) 的值直接传到最后一个then里。
输出结果是1
2、深拷贝
这个常常让你手写
来一版本简单的
function deepCopy(original) {
if (Array.isArray(original)) {
return original.map(elem => deepCopy(elem));
} else if (typeof original === 'object' && original !== null) {
return Object.fromEntries(
Object.entries(original)
.map(([k, v]) => [k, deepCopy(v)]));
} else {
// 原始类型值无需拷贝
return original;
}
}
来一版本解决互相引用问题的
const deepClone = (obj) => {
// 非引用类型及函数将直接返回
if (!obj || typeof obj !== 'object') return obj;
// 特殊的引用类型处理
switch (Object.prototype.toString.call(obj).slice(8, -1)) {
case 'Date':
return new Date(obj);
break;
case 'RegExp':
return new RegExp(obj);
break;
case 'String':
return new String(obj);
break;
case 'Number':
return new Number(obj);
break;
case 'Boolean':
return new Boolean(obj);
break;
}
const map = deepClone.map = deepClone.map || new Map();
// 使用map结构可以不必循环缓存,提高效率
if (map.get(obj)) {
return map.get(obj);
}
const result = obj instanceof Array ? [] : {};
// 如果仔细观察可以发现解决了同层同引用的问题
map.set(obj, result);
for (let propName in obj) {
if (obj.hasOwnProperty(propName)) {
result[propName] = deepClone(obj[propName]);
}
}
return result;
}
3、for in与for of
我经常区分不了
数组:for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值。
对象:for in 可以遍历到myObject的原型方法method,如果不想遍历原型方法和属性的话,可以在循环内部判断一下,hasOwnPropery方法可以判断某属性是否是该对象的实例属性
for in 遍历数组,会把数组原型上的methods也给遍历了
4、 cookie与storage区别
深入了解浏览器存储:对比Cookie、LocalStorage、sessionStorage与IndexedDB - 掘金
cookie主要用于存储用户登录信息
storage主要用于存储一些不必每次请求都要带到服务器的一些信息
共同点:都是保存在浏览器端,且都遵循同源策略。
不同点:在于生命周期与作用域的不同
与服务器通信:cookie会参与,storage不参与
作用域:localStorage只要在相同的协议、相同的主机名、相同的端口下,就能读取/修改到同一份localStorage数据。sessionStorage比localStorage更严苛一点,除了协议、主机名、端口外,还要求在同一窗口(也就是浏览器的标签页)下
大小:cookie一般大小为4kb,而storage的大小为5M
存储形式:只能存储字符串,想要得到对象,需要对字符串进行解析
使用途径
cookie用于存储用户登录信息
Cookie是用来维护用户信息的,而域名(domain)下所有请求都会携带cookie,但对于静态文件的请求,携带cookie信息根本没有用,此时可以通过cdn(存储静态文件的)的域名和主站的域名分开来解决。
HttpOnly 不支持读写,浏览器不允许脚本操作document.cookie去更改cookie, 所以为避免跨域脚本 (XSS) 攻击
localStorage
考虑到 LocalStorage 的特点之一是持久,有时我们更倾向于用它来存储一些内容稳定的资源。比如图片内容丰富的电商网站会用它来存储 Base64 格式的图片字符串
用来提升网页首屏渲染速度(根据第一请求返回时,将一些不变信息直接存储在本地)。
localStorage.setItem(“key”,”value”);
localStorage.getItem(“key”);
localStorage.removeItem(“key”);
localStorage.clear();
sessionStorage
sessionStorage 更适合用来存储生命周期和它同步的会话级别的信息。这些信息只适用于当前会话,当你开启新的会话时,它也需要相应的更新或释放。比如微博的 sessionStorage就主要是存储你本次会话的浏览足迹:
sessionStorage保存的数据用于浏览器的一次会话,当会话结束(通常是该窗口关闭),数据被清空;sessionStorage 特别的一点在于,即便是相同域名下的两个页面,只要它们不在同一个浏览器窗口中打开,那么它们的 sessionStorage 内容便无法共享;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。除了保存期限的长短不同,SessionStorage的属性和方法与LocalStorage完全一样。
基于上面的特点,sessionStorage 可以有效对表单信息进行维护,比如刷新时,表单信息不丢失。
方法同localStorage
session
1,session 在服务器端,cookie 在客户端(浏览器)
2,session 默认被存在在服务器的一个文件里(不是内存)
3,session 的运行依赖 session id,而 session id 是存储在 cookie 中的,也就是说,如果浏览器禁用了 cookie ,那么 session 就会失效(但是可以通过其它方式实现,比如在 url 中传递 session_id)
4,session 可以放在 文件、数据库、或内存中都可以。
5,用户验证这种场合一般会用 session