广州最近面试一些高频面试题归纳(js+es6篇)
跨域是指从一个域名的网页去请求另一个域名的资源时,域名、端口、协议只要有一个不同就会造成跨域
1.jsonp
既然它叫jsonp,很明显目的还是json,而且是跨域获取。根据上面的分析,很容易想到:
利用js构造一个script标签,把json的url赋给script的scr属性,把这个script插入到
dom里,让浏览器去获取。
JSONP是一种可以绕过浏览器的安全限制,从不同的域请求数据的方法。
JSONP请求不是ajax请求,是利用script标签能加载其他域名的js文件的原理,来实现跨
域数据的请求。
特点: 1.只能为get请求。
2.接口必须有回调函数的执行。
3.支持所有浏览器,因为它是script标签。
2、服务器代理
由于浏览器有同源策略限制,(同源策略即协议域名端口相同),所以想要跨域访问其他域
下的资源,需要绕开浏览器的这个限制,可以在服务器端设置一个代理,由服务器端向跨域
下的网站发出请求,再将请求结果返回给前端,成功避免同源策略的限制。此时前端相当于
不跨域,和正常请求一致,无需额外配置。
灵活性:不同环境服务域名可能不一致,因此nginx配置也不相同,不便于移植。
3、CORS
CORS跨源资源分享(Cross-Origin Resource Sharing)的缩写,它为Web服务器定义了一
种方式,允许网页从不同的域访问其资源。
特点: 1、JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
2、使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起
JSONP有更好的错误处理。
3.CORS不支持IE8以下浏览器,但是绝大多数现代浏览器都已经支持了CORS。
4.灵活性,只需要在代码或者配置中心进行黑白名单配置即可,方便一直和拓展。
1、原型是指一个可以被克隆的类,通过复制原型可以创建一个一模一样的新对象。
其实原型就相当于一个模板,它包含如下:
1.它所有的引用类型都包括一个_ proto _(隐式原型)的属性,属性是一个普通的对象。
2.所有构造函数都是有一个prototype(原型)属性,属性是一个普通的对象。
3.所有引用类型的_ proto 属性指向它的构造函数的prototype,即a为一个数组,
a. _ proto_ === Array.prototype
2、原型链是指当访问一个对象的某个属性时,会先从该函数本身属性上找,如果没有找到,则会在他
的 _ proto _隐式属性(即构造函数的prototype)上去找,如果还没有找到的话,则就会再去
prototyep的 _ proto _ 中去找,这样一层一层向上查找就会形成一个链式结构,就称之为原型链。
ajax: 1.AJAX不是新的编程语言,而是一种使用现有标准的新方法。
2.最大优点是在不加载整个页面,可以与服务器交换数据并局部刷新网页内容。
3.不需要任何浏览器插件,但需要用户允许js在浏览器执。
axios: axios是通过promise实现对ajax技术的一种封装
1.用于浏览器和node.js的基于promise的HTTP的客户端
2.从浏览器制作XMLHttoRequests
3.让HTTP从node.js请求
4.支持promise API
5.拦截请求和相应(Interceptors拦截器)
6.转换请求和响应数据
7.取消请求
8.自动转换为JSON数据
9.客户端支持防止CSRF/XSRF(跨站请求伪造)
浅复制: 浅复制只会依次复制对象的每一个属性,不会对这些属性进行递归复制。
只是对复制对象的引用,栈和堆的关系,像number与string,boolean,null是堆的,直接可以用。
深复制: 深复制需要层层递归,复制对象的所有属性,包括对象属性的属性的属性...
1.for循环/遍历实现对象的深拷贝
2.转换成json再转换成对象实现对象的深拷贝
(json.parse(Json.strinify(arr)))
1、利用Array.from(new Set(数组))去重:
const test = ['q', 'w', 'e', 'q', 'u', 'p']
Array.from(new Set(test))
2、利用includes去重:
const test = ['q', 'w', 'e', 'q', 'u', 'p']
let newList = []
test.forEach((item) => {
if (!newList.includes(item)) {
newList.push(item)
}
})
3、利用[new Set(数组)]去重:
const test = ['q', 'w', 'e', 'q', 'u', 'p']
[new Set(test)]
数据类型主要包括两部分:
基本数据类型: Undefined、Null、Boolean、Number 和 String
引用数据类型: Object (包括 Object 、Array 、Function)
以及新增的: Symbol(ES6中引入的一种新的基本数据类型,用于表示一个独一无二的值)
1、join() :将数组中所有元素根据设置的字符串拼接成一个字符串;
2、reverse() :数组翻转;
3、concat() :数组拼接,返回新数组;
4、slice(start, end) :截取数组,返回新数组;
5、splice(start, lengtn, newValue) :从数组中删除、插入元素,返回一个由删除元素组成的数
组(返回新数组,并且修改了原数组);
6、push() :数组末尾添加元素,返回数组新长度;
7、pop() :数组末尾删除元素,返回被删除的元素(删且删除1个);
8、shift() :数组前添加元素,返回数组新长度;
9、unshift() :数组前删除元素,返回被删除的元素(删且删除1个);
10、toString() :将数组的每个元素都转化为字符串并且用逗号拼接;
11、indexOf() 和 lastIndexOf():查找元素的想的索引位置;
12、sort() :默认按照字母升序排序(元素自动转化为字符串进行比较);
这里就不列举太多
区别: 1、http是明文传输协议,https是加密传输协议
2、http没有证书,https有ssl的CA安全证书,安全性更高
3、浏览器显示标识不同,https有绿色安全标识,http则是不安全标志
1、typeof可以准确判断除了null的基本类型,null和对象都会返回object
2、instanceof能判断对象的类型或者数组类型
3、arr instanceof Array
4、Object.prototype.toString.call(arr)
5、Array.isArray(arr)
1、let和const
let 只能在块级作用域内访问。
const 用来定义常量,必须初始化,不能修改(对象特殊)
2、扩展运算符...
3、箭头函数
4、Object.keys()、Object.values()、Object.entries()
Object.keys() 返回对象所有属性
Object.values() 返回对象所有属性值
Object.entries() 返回多个数组,每个数组是 key–value
5、includes(),map(),filter(),forEach(),Array.from()等方法,其他不一一列举
includes()查看数组中是否存在这个元素,存在就返回true,不存在就返回false。
map()利用原数组经过运算后的数组,或者从对象数组中拿某个属性。
filter()将符合挑选的筛选出来成为一个新数组,新数组不会影响旧数组。
forEach()循环遍历数组中的每一项,没有返回值。
Array.from()方法可以将可迭代对象转换为新的数组。
6、模板字符串,用`${}`
7、promise
1、闭包就是函数嵌套函数,将函数作为函数的返回值返回出来,从而使全局拿到函数的变量,即f2作为
f1的返回值返回出来,从而使全局能拿到f1的变量。
2、使用闭包主要为了设计私有的方法和变量,闭包的优点是可以避免变量的污染,缺点是闭包会常驻内
存,会增大内存使用量,使用不当很容易造成内存泄露。在js中,函数即闭包,只有函数才会产生作
用域的概念。
3、闭包有三个特性:
函数嵌套函数
函数内部可以引用外部的参数和变量
参数和变量不会被垃圾回收机制回收
4、闭包的缺点就是常驻内存,会增大内存使用量,容易造成内存泄漏
1、防抖是触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。适用
于可以多次触发但触发只生效最后一次的场景。
function debounce(fn, delay){
let timer = null;
return function(){
clearTimeout(timer);
timer = setTimeout(()=> {
fn.apply(this, arguments);
}, delay)
}
}
2、节流是高频事件触发,但在n秒内只会执行一次,如果n秒内触发多次函数,只有一次生效,节流会稀释函
数的执行频率。
function throttle(fn, delay) {
let flag = true;
return function() {
if (flag) {
setTimeout(() => {
fn.call(this);
flag = true;
}, delay)
}
flag = false;
}
}
window.onscroll = throttle(function() {
console.log(1);
}, 500)
1、重绘(repaint):当元素样式的改变不影响页面布局时,比如元素的颜色,浏览器将对元素进行的更新,
就是重绘。
常见的重绘操作有:
1.改变元素颜色
2.改变元素背景色
2、回流(reflow):当元素的尺寸或者位置发生了变化,就需要重新计算渲染树,这就是回流,比如元素的
宽高、位置,浏览器会重新渲染页面,就是回流,又叫重排
常见的重绘操作有:
1.改变元素宽高
2.改变位置或者移动
3、关系:回流必定会触发重绘,重绘不一定会触发回流。重绘的开销较小,回流的代价较高。
区别一:
循环数组情况下,都可以循环数组,for in输出的是数组的下标索引,而for of输出的是数组的每一
项的值
区别二:
循环对象情况下,forin可以循环遍历对象,for of不能遍历对象,只能遍历带有iterator接口的,
比如Map,Set,Array等
总体来说,for in适合遍历对象,for of适合遍历数组,当然看具体应用场景
第一种:
localStorage.setItem('myData', '123456')
// 设置一小时的有效期
const expire = 1000 * 60 * 60;
setTimeout(() => {
localStorage.removeItem('password')
}, expire)
第二种:
// 存储数据
const data = {
value: 'example data',
timestamp: new Date().getTime() // 添加当前时间戳
};
localStorage.setItem('myData', JSON.stringify(data));
// 获取数据并检查时间戳
const storedData = JSON.parse(localStorage.getItem('myData'));
const timestamp = storedData.timestamp;
const expirationTime = 24 * 60 * 60 * 1000; // 24小时
if (new Date().getTime() - timestamp > expirationTime) {
// 数据过期,从localStorage中删除
localStorage.removeItem('myData');
} else {
// 数据未过期,继续使用
const value = storedData.value;
console.log(value);
}
写的不好的,希望大佬们指出~