二阶段企业面试真题(2103+2104)
二阶段企业面试真题
1、引用类型和基本类型的区别
基本类型有:Undefined、Null、Boolean、Number、String、Symbol
引用类型有:统称为 Object 类型。
1)、内存的角度:
基本类型在内存中,占据一块空间,空间里存储的就是数据,获取数据是直接获取
引用类型在内存中,占据两块空间,第一块存储的是地址,第二块存储的是数据,获取数据是属间接取值
2)、赋值的角度
基本类型赋的就是值,引用类型赋的就是地址
3)、函数传参
基本类型传的是值,引用类型传的是地址
2、null和undefined区别
https://blog.csdn.net/jiang7701037/article/details/79303829
undefined:定义变量后,没有赋值
null:对象没有引用的值,即就是引用类型里没有存储地址
3、js中的== 和 ===区是什么
https://blog.csdn.net/jiang7701037/article/details/85200401
三等是数据和类型都相等, ==会尝试进行类型转换
4、Let ,const、var的区别[越详细越好) 扩展;它们的存储位置
https://blog.csdn.net/jiang7701037/article/details/83929296
https://blog.csdn.net/jiang7701037/article/details/83929371
相同点:都是用来定义变量的
不同点:
1)、声明提升:var会声明提升,let和const不会
2)、作用域:var是全局作用域和函数作用域,let和const是块级作用域(包括全局和函数作用域)
var定义的全局变量是window对象的属性,let和const定义的全局变量不是window的属性
3)、多个同名的变量:var可以,let和const不行
4)、暂时性死区:var没有,let和const有
5)、let在循环里,可以暂存循环变量
6)、const定义的变量是常量,必须赋初始值而且不可修改
5、const 定义一个数组,改变下标0的值,会报错吗
不会报错,const修饰的是数组,而不是数组的元素。
补充:const修饰引用类型时,都修饰的是地址。而不是数据。
6、for循环里let换成var会发生什么
① 如果换成var,for 循环定义的迭代变量会渗透到循环体外部
② let在循环里会暂存变量,如果在循环的时候向外输出定义的变量,得到的是当前的迭代变量,换成var向外输出都是已经循环结束的结果
7、this的指向,箭头函数的this
https://blog.csdn.net/jiang7701037/article/details/111837813
this是函数的内置对象,this是代名词,所以,this代表哪个对象,要看函数属于哪种情况。
this的指向有四种情况:
①当this所在函数是事件处理函数时,this代表事件源
②当this所在函数是构造函数时,this代表new出来的对象
③当this所在函数时类的方法时,this代表调用方法的对象。
④当this所在函数没有明确的所属对象,this代表window对象。
另外:箭头函数根本没有自己的this,它内部的this就是外层代码块的this
补充:
其实,this表示什么意思,更多要看调用,要看运行,不要只看函数的定义。因为在调用时,有可能this的指向会被改变。
8、call, apply,bind的区别[说一说基本原理]
相同点:三个函数都会改变this的指向(调用这三个函数的函数内部的this)
不同点:
1)、bind会产生新的函数,(把对象和函数绑定死后,产生新的函数)
2)、call和apply不会产生新的函数,只是在调用时,绑定一下而已。
3)、call和apply的区别,第一个参数都是要绑定的this,apply第二个参数是数组(是函数的所有参数),call把apply的第二个参数单列出来。
9、普通函数和箭头函数的区别
1.写法格式不同
2.箭头函数不能作为构造函数使用
3.箭头函数中没有this和arguments
4.箭头函数不具有prototype原型对象
5.箭头函数不具有super
10、箭头函数的作用(跟普通函数的区别) 简要描述下ES6中的箭头函数以及其使用场景
①.箭头函数使表达更加简洁
②.最主要的目的就是解决this指针的问题
使用场景:
1.简单的函数表达式,内部没有this引用,没有递归,事件绑定,解绑定
2.内层函数表达式,需要调用this,且this应与外层函数一致时(保证指向vue实例)
11、原型和原型链
1)、原型:
每个函数都会有一个属性prototype。这个属性就是原型属性。JavaScript在实现面向对象时,会经常使用原型。每个对象(实例)的有一个属性( __ proto __)指向构造函数的prototype属性(prototype指向的内存区域)。prototype属性里保存着所有对象(实例)共享的属性和方法。
2)、原型链:当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的 __ proto __ 隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会再在构造函数的prototype的 __ proto __中查找,这样一层一层向上查找就会形成一个链式结构,我们称为原型链。
12、作用域和作用域链
https://blog.csdn.net/jiang7701037/article/details/101314293
作用域,就是变量起作用的区域(范围)。或者说,js代码执行时,查找变量的范围。
作用域链是指:当js编译器在寻找变量时,先在最近的作用域(花括号)里找,如果找不到,则朝上一级作用域(花括号)里找,依次类推,直到找到或者找不到为止。这就是作用域链。
13、Ajax的步骤与封装 AJAX中的200和4分别是什么意思
ajax的流程,readyState和status的意思
1、创建XMLHttpRequest
let xhr = new XMLHttpRequest()
2、设置(请求方式,请求路径,请求参数)
xhr.open("get", "regSave.php?username=jzm&userpass=123", true)
3、设置回调函数(后端有响应时,调用的回调函数)
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
xhr.responseText //后端响应的内容,如:php中的echo 后面跟的内容
}
}
4、发送
xhr.send();
//readyState:请求响应的状态(请求响应进行到哪一步了)
//status:响应结果的描述,是个状态码(数字)
readyState==4:表示请求响应的过程完毕
status==200:表示请求响应的结果----拿到了值
14、深浅拷贝 区别以及如何进行深拷贝
https://blog.csdn.net/jiang7701037/article/details/98738487
场景:
说深拷贝和浅拷贝,特指引用类型。
区别:
深拷贝: 把引用类型的地址及其它的数据都拷贝一份
浅拷贝: 只拷贝了引用类型的地址
如何进行深拷贝:
深拷贝的思路:
创建空对象,循环原对象的每个键,一一赋值给空对象,并使用递归的方式,把对象属性也进行复制,以下为示例代码:
// 功能:封装一个深拷贝的函数
// 参数:被拷贝的对象
// 返回值:拷贝的对象
function copyObj(obj){
let newObj ={};
for(let key in obj){
if(typeof obj[key] == "object"){ //如果说当前属性是对象的话,那么再做深拷贝
newObj[key] = copyObj(obj[key]);
}else{
newObj[key] = obj[key];
}
}
return newObj;
}
var obj1= {
name:"张三疯",
sex:"男",
address:{
province:"陕西",
city:"西安"
}
}
let obj2 = copyObj(obj1);
https://blog.csdn.net/jiang7701037/article/details/98738487
15、promise promise都有哪几种状态 其执行状态
概述:Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,可以获取异步操作的消息
作用: (1)、避免回调地狱的问题(2)、Promise对象提供了简洁的API,使得控制异步操作更加容易
Promise有三种状态:
pendding :正在进行中,
rejected :失败,
resolved : 成功
基础用法:new Promise(function(resolve,reject){ })
16、数组去重的方法
①利用数组indexof方法
function unique(arr) {
var arr1 = [];
for (var i = 0; i < arr.length; i++) {
if (arr1.indexOf(arr[i]) == -1) {
arr1.push(arr[i]);
}
}
return arr1;
}
console.log([1,1,2,2,3,3,3,4,5,6,6,6,7]);//1,2,3,4,5,6,7
②ES6的Set
function unique(arr){
return [...new Set(arr)]
}
console.log(unique([1,2,1,2,2,3,2,1]));
17、js如何创建数组,js数组都有哪些方法?
1、有两种创建方式:
①字面量创建: var arr=[];
②构造函数创建: var arr1=new Array();
2、js数组的方法:
push 尾增
pop 尾删
unshift 头增
shift 头删
concat 数组拼接
join 数组转字符串
reverse 逆序
sort 按字符串UniCode码排序
map 对数组的每个元素做某个处理,参数是回调函数,并且有返回值
slice 复制
indexOf 查找数组中的元素,找到返回该元素下标, 没找到返回-1
splice 截取
filter 过滤
every 对数组中的每一项进行判断,若都符合则返回true,否则返回false
some 对数组中的每一项进行判断,若都不符合则返回false,否则返回true(有没有?)
reduce:将数组所有数值进行叠加返回
forEach 对数组的每个元素做某个处理,参数是回调函数
18、同一个数组,同样的限制条件,map和filter find返回值有什么区别
相同点:都不会改变原数组
不同点:
map返回值是一个新的数组,新数组中的元素为原始数组中的元素调用函数处理后的值。
find返回值:返回数组中符合条件的第一个元素的值! 返回值不是数组!
filter返回值:返回一个新数组 是原数组中符合条件的所有元素。
19、延时器(宏任务微任务)
https://blog.csdn.net/jiang7701037/article/details/95887439
1)、宏任务(macrotask )
宏任务一般包括: setTimeout,setInterval,I/O 操作(包括AJAX请求),即上面的示例中setTimeout是宏任务。
2)、微任务(microtask )
微任务一般包括:promise.then() 里的操作
20、闭包 什么情况下会使用闭包
概念:定义在一个函数内部的函数,并且这个内部函数能够在外层函数外访问到外层函数中定义的变量
作用:
①让在外部访问函数内部变量成为可能
②局部变量会常驻在内存中
③可以避免使用全局变量,防止全局变量污染
缺点:
会造成内存泄露(内存空间长期被占用,而不被释放)
21、网络协议
网络协议为计算机网络中进行数据交换而建立的规则、标准或约定的集合。
常见的协议有:HTTP,HTTPS、TCP/IP
HTTP和HTTPS的区别?
HTTP(HyperText Transfer Protocol:超文本传输协议) 简单来说就是一种发布和接收 HTML 页面的方法,被用于在 Web 浏览器和网站服务器之间传递信息。
HTTP 默认工作在 TCP 协议 80 端口,用户访问网站 http:// 打头的都是标准 HTTP 服务。
HTTP 协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。
HTTPS(Hypertext Transfer Protocol Secure:超文本传输安全协议)是一种通过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS(安全套接层/传输层安全协议) 来加密数据包。HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。
区别:
- HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
- 使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。
- HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
- http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
- HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源。
22、函数节流和事件防抖
https://blog.csdn.net/jiang7701037/article/details/99976154
函数节流:
意思:不要调用太频繁,如每隔多少毫秒就调用一次
使用场景: 比如页面无数次的滚动时就会触发无数次的onscroll,但是我希望调用函数不要那么频繁
解决思路:只要页面一滚动,就启动一个定时器,在很多次滚动过程中,如果计时器还没有停,则不调用函数,如果计时器停了,那就函数就已经调用一次完毕,然后再重新启动一个定时器
let i = 0;
let myTimer = null;
window.onscroll = function(){
//无数次的滚动过程中,
//1、如果计时器还没有停(myTimer!=null),则不执行下面的代码(即:直接return)。
//2、如果计时器停了(myTimer==null),说明一次执行完毕,则重新再启动定时器。
if(myTimer!=null){
return;
}
//启动定时器,时间间隔是200ms。
myTimer = setTimeout(()=>{
console.log(i++);
myTimer =null;
},200);
}
事件防抖:
概念:
有一些事件的触发比较频繁,但是,我们只希望这无数次的事件触发中,有部分事件是有效的(如:用户有短暂的停止时才调用函数)。特别是在触发一次,就发一次请求,会有无数次的抖动。
如: 键盘事件:onkeydown,onkeyup,onkeypress,oninput,都是按一次键,触发一次.触发非常频繁。
使用场景:
搜索框(百度搜索框,淘宝,京东等等),每次用户输入内容都需要发一次请求,从后端拿到关键字对应的内容.
特别是输入汉字时:我们希望用户输入完成汉字时再触发(发送请求),但是,实际情况是:当用户输入一个字母时,就会触发一次事件(发送一次请求)
记住:用户的输入习惯:当输入完一个汉字后,或者若干个汉字后,会有短暂的停顿。而在连续输入字母的过程中,不会有停顿。事件防抖的思路就是利用这个短暂停。
解决思路:
我们可以设置一个定时器,在每次输入时,先清除上一次的定时器,如果本次输入和上次输入之间的时间间隔大于我们设置的毫秒数时,上次输入的内容就会发送请求。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
ul{
list-style: none;
}
</style>
</head>
<body>
<input type="text" id="querystr">
<input type="submit" value="百度一下">
</body>
</html>
<script>
let myTimer = null;
$("querystr").oninput = function(){
//在每次输入时,先清除上一次的定时器,清除了定时器后,就不会发送请求了。
//即本次输入和上次输入的间隔非常短(小于100ms)时,上次定时器的代码就不会执行,也就不会发请求了。
//如果本次输入和上次输入之间的时间间隔大于100ms时,上次输入的内容就会发送请求。
if(myTimer!=null){
window.clearTimeout(myTimer);
}
myTimer = setTimeout(()=>{
let scriptDom = document.createElement("script");
scriptDom.src = 'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=' + this.value + '&json=1&p=3&sid=1438_24869_21080_18560_17001_25177_22160&req=2&bs=1%2B&pbs=1%2B&csor=2&pwd=1%3D&cb=f&_=1511334117083';
document.body.appendChild(scriptDom);
scriptDom.remove();
},100);
}
function f(data){
console.log(data);
let htmlStr = "";
data.s.forEach((item)=>{
htmlStr+=`<li>${item}</li>`;
});
$("search-list").innerHTML = htmlStr;
}
</script>
23、跨域的解决方案
1、jsonp
可以使用jsonp来完成跨域,本质上是利用HTML标签的 src属性可以跨域的特性
2、CORS
3、反向代理
24、统计字符串中字母个数
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
请输入原始字符串:
<input id="textId" type="text" value="aabccdeefff" /><br/>
<input type="button" value="压缩" onclick="compress()" /><br/>
压缩后的字符串:<input id="resultId" type="text" /><br/>
</body>
</html>
<script type="text/javascript">
function $(id){
return document.getElementById(id);
}
//统计字符串中每个字符的个数。(“aabccdeefff”,a2 b1 c2 d1 e2 f3)
function compress(){
//1、获得用户输入
var str = $("textId").value;
//2、逻辑
//定义变量(当前字符,坐庄的字符)
var currChar = str.charAt(0);
//定义变量(记录当前字符重复的次数,坐庄的次数)
var count = 1;
var resultStr="";//保存结果
for(var i=1;i<str.length;i++){
if(str.charAt(i)==currChar){//如果当前字符和庄家一样,就计数
count++;
}else{//换庄家了
//把前一个庄家和数量拼接到resultStr。
resultStr += currChar+count;
//换庄家
currChar = str.charAt(i);
//把计数器重新置为1.
count=1;
}
}
//把最后一个庄家的字符和数量进行拼接
resultStr += currChar+count;
//3、输出
$("resultId").value =resultStr;
}
</script>
25、js运行机制
从上到下开始执行,同步代码一直往下走,异步代码放到队列当中,然后继续走同步,同步走完之后,然后是事件循环,走事件队列,执行满足条件的回调,并根据情况决定执行完成之后是否注销回调
26、事件流,讲讲事件冒泡与事件捕获、事件委托是事件冒泡还是事件捕获,为什么)
当某个事件执行时,从子元素向父元素触发 或 从父元素向子元素触发 称为事件流
事件流分为三个阶段:捕获阶段,事件源,冒泡阶段
事件流的两种模式:
事件冒泡:从子元素向父元素触发 -->当某个事件触发时,同样的事件会向父元素触发。
事件捕获:从父元素向子元素触发
事件委托是利用事件的冒泡原理来实现的
原理:当我们想给很多个子标签添加同一个事件的时候,可以给它的父级元素添加对应的事件,当触发任意子元素时,会冒泡到父级元素里,这时绑定在父级元素的事件就会被触发,这就是事件代理(委托),委托他们的父级代为执行事件。
作用:代码简洁;减少浏览器内存的使用
27、cookie存在即合理,为什么存在这个?这个是请求服务端 还问为什么localStorage能永久性存储
1)、cookie是在HTML4中使用的给客户端保存数据的,也可以和session配合实现跟踪浏览器用户身份,
2)、localstorage 永久性存储是因为它是在硬盘中存储的
28、cookie,localStorage,sessionStorage 的区别
https://blog.csdn.net/jiang7701037/article/details/89118086
相同点:
都是在客户端保存数据的,存储数据的类型都是字符串
不同点:
- 生命周期:
1)、cookie如果不设置有效期,那么就是临时存储(存储在内存中),是会话级别的,会话结束后,cookie也就失效了,如果设置了有效期,那么cookie存储在硬盘里,有效期到了,就自动消失了。
2)、localStorage的生命周期是永久的,除非主动删除数据,否则数据永远不会消失。
3)、sessionStorage,可以理解成没有设置有效期的cookie,也是会话级别的,只要浏览器窗口不关闭,数据就会一直存在
-
大小限制:
cookie大小限制在4KB,非常小;webstorage在5M
-
网络流量:
cookie的数据每次都会发给服务器端,webstorage不会与服务器端通信,所以,webstorage更加节约网络流量
- 安全性:
WebStorage不会随着HTTP header发送到服务器端,所以安全性相对于cookie来说比较高一些,不会担心截获。
- 使用方便性上:
WebStorage提供了一些方法,数据操作比cookie方便;
28、发布者,订阅者模式
29、map、set是什么 map中怎样把value改为数组????
1)、
map是集合,存储的每个元素是键值对。
set也是集合,但是存储的元素不能重复(相当于没有重复元素的数组)
2)、map怎样把value改为数组:
map对象的values方法
30、es6面向对象 面向对象编程思想(说一下一对一和一对多)
-
es5和es6的继承 es5和es6的区别
-
冒泡排序
-
获取dom元素
-
如有两个字符串的版本号比如V2.12.0和V2.7.0,如何比对它两的大小
-
请求方式get和post的区别
-
如何判断请求成功或者失败
-
getTime,parseInt,parFloat
-
请解释—下JavaScript的同源策略
-
为验证手机号写一个正则
-
用js递归的方式写1到100求和
-
如何中断 ajax 请求
-
javascript事件中,event.preventDefaut()、event stopPropagation()有什么区别?
阻止默认 event.stopPropagation()
阻止默认行为 event.preventDefault()
-
http请求过程
-
简述你常用的代码命名规范的主要内容
-
简单解释一下什么是CSRF攻击,并给出常用的防范措施
-
你所了解的CSS 预处理器都有哪些?它们与传统CSS相比的优点是什么?
-
forEach和map的区别
-
除了闭包还有什么可以 造成内存泄露
内存泄漏:内存空间长期被占用,而不被释放
闭包:函数内部定义函数,并且这个内部函数能够访问到外层函数中定义的变量(准确的说是声明的参数和变量)
特点
1、让外部访问函数内部变量成为可能。
2、局部变量会常驻在内存中。
3、可以避免使用全局变量,防止全局变量污染。
4、会造成内存泄漏(内存空间长期被占用,而不被释放)
在地址栏输入一个url会发生什么
https://blog.csdn.net/jiang7701037/article/details/85462359
1.用户在浏览器中打回车
2.浏览器读取地址栏中读取到url
浏览器开始识别url中的协议(http,https,ftp等等)
域名解析
查找本地的hosts文件,本地host有对应的ip地址,就向该ip地址发送请求(解释:hosts文件是一个没有扩展名的系统文件,它的主要作用是能加快域名解析,还可以屏蔽网站等。)
如果本地hosts没有,就找本地的域名服务器(DNS),如果本地域名服务器没有,没有就找根域名服务器。(解释:本地DNS一般是指你电脑上网时IPv4或者IPv6设置中填写的那个DNS。这个有可能是手工指定的或者是DHCP自动分配的)
根据ip地址访问服务器
3.浏览器访问服务器:
浏览器根据解析后的ip地址访问服务器:浏览器发送tcp连接(三次握手),建立tcp连接后,发送http请求。- 服务器处理请求,并响应给前端:
服务器接收到浏览器端的请求后,
会根据请求的地址,找对应的文件
如果是动态的资源(如:php,jsp,py等等),则服务器端会执行该文件的代码,把执行的结果,发给浏览器端
如果是静态资源(HTML,CSS,JS,图片,声音等等),则直接发给浏览器端
5. 浏览器接收服务器端的响应
浏览器端接收到服务器响应的结果,开始进行解析HTML代码,解析时,如果碰到静态资源的连接(如:,
),则再次发送请求。6.浏览器最终显示出了页面
关于浏览器如何解析HTML代码和渲染过程,我在后续文章中再写 - 服务器处理请求,并响应给前端:
-
事件委托
事件委托是利用事件的冒泡原理来实现的
当我们想给很多个子标签添加同一个事件的时候,可以委托他们的父级代为执行事件
作用:代码简洁;减少浏览器内存的使用
-
判断一个对象是空对象的方法
-
Dom创建,添加,复制,删除节点
-
display:none visibility hidder的区别
-
伪类和伪元素都有哪些
-
Promise和 Callback有什么区别?
-
浏览器的内核分别是什么?经常遇到的浏览器的兼容性有哪些?
-
JavaScript 中趣何检测一个变量是一个String类型?请写函数实现
-
split() join()的区别
split()将字符串以某个字符分割成数组join()将数组以某个字符组合成一个字符串 -
简述同步和异步的区别?
-
前端页面有哪三层构成,分别是什么?作用是什么? 答:html css javascript 结构 样式 行为

浙公网安备 33010602011771号