【面试】545- 分享37道 JavaScript 常见面试题
NeverSettle
https://juejin.im/post/5e464c4ef265da5756324a2b
1.如何理解 JS 中的this关键字?
this表示当前对象,this的指向是根据调用的上下文来决定的,默认指向window对象。
全局环境:全局环境就是在里面,这里的this始终指向的是window对象。
局部环境:
1.在全局作用域下直接调用函数,this指向window。
2.对象函数调用,哪个对象调用就指向哪个对象。
3.使用 new 实例化对象,在构造函数中的this指向实例化对象。
4.使用call或apply改变this的指向。
2. JavaScript 中的作用域(scope)是指什么?
在 JavaScript 中,每个函数都有自己的作用域。作用域基本上是变量以及如何通过名称访问这些变量的规则的集合。只有函数中的代码才能访问函数作用域内的变量。
同一个作用域中的变量名必须是唯一的。一个作用域可以嵌套在另一个作用域内。如果一个作用域嵌套在另一个作用域内,最内部作用域内的代码可以访问另一个作用域的变量。
3.什么是闭包
我第一次解释闭包时,我常说函数中的函数;但是,它没有正确地描述闭包的确切含义。
闭包是在另一个作用域内创建一个封闭的词法范围。它通常会自动返回来生成这个词法环境。这个环境由创建闭包时在作用域内的任何局部变量组成。它就像一个微型工厂,用这些原料生产出具有特定功能的产品。
4. 解释 JavaScript 中的相等性。
JavaScript 中有严格比较和类型转换比较:
严格比较(例如 ===)在不允许强制转型的情况下检查两个值是否相等;
抽象比较(例如 ==)在允许强制转型的情况下检查两个值是否相等。
var a = "42";
var b = 42;
a == b; // true
a === b; // false
复制代码如果被比较的任何一个值可能是 true 或 false,要用 ===,而不是 ==;
如果被比较的任何一个值是这些特定值(0、“”或 []),要用 ===,而不是 ==;
在其他情况下,可以安全地使用 ==。它不仅安全,而且在很多情况下,它可以简化代码,并且提升代码可读性。
5. 解释一下变量的提升
变量的提升是JavaScript的默认行为,这意味着将所有变量声明移动到当前作用域的顶部,并且可以在声明之前使用变量。初始化不会被提升,提升仅作用于变量的声明。
var x = 1
console.log(x + '——' + y) // 1——undefined
var y = 2
6.如何理解事件委托
在DOM树上绑定事件监听器并使用JS事件处理程序是处理客户端事件响应的典型方法。从理论上讲,我们可以将监听器附加到HTML中的任何DOM元素,但由于事件委派,这样做是浪费而且没必要的。
什么是事件委托?
这是一种让父元素上的事件监听器也影响子元素的技巧。通常,事件传播(捕获和冒泡)允许我们实现事件委托。冒泡意味着当触发子元素(目标)时,也可以逐层触发该子元素的父元素,直到它碰到DOM绑定的原始监听器(当前目标)。捕获属性将事件阶段转换为捕获阶段,让事件下移到元素; 因此,触发方向与冒泡阶段相反。捕获的默认值为false。
7.解释一下严格模式(strict mode)
严格模式用于标准化正常的JavaScript语义。严格模式可以嵌入到非严格模式中,关键字 ‘use strict’。使用严格模式后的代码应遵循JS严格的语法规则。例如,分号在每个语句声明之后使用。
8.解释 JavaScript 中的 null 和 undefined。
JavaScript 中有两种底层类型:null 和 undefined。它们代表了不同的含义:尚未初始化:undefined;空值:null。
//null和undefined是两个不同的对象
null == null //true
null === null //true
null == undefined //true
null === undefined //flase
9.解释 JavaScript 中的值和类型。
JavaScript提供两种数据类型: 基本数据类型和引用数据类型 基本数据类型有:
String
Number
Boolean
Null
Undefined
Symbol
引用数据类型有:
Object
Array
Function
10.解释事件冒泡以及如何阻止它?
事件冒泡是指嵌套最深的元素触发一个事件,然后这个事件顺着嵌套顺序在父元素上触发。防止事件冒泡的一种方法是使用 event.cancelBubble 或 event.stopPropagation()(低于 IE 9)。
11.window.onload的作用?
window.onload是等文档和资源都加载完成后调用的事件,保证js获取元素 的时候,已经加载。
12.说说你对作用域链的理解?
作用域链是js中的一种查找机制,从当前作用域查找,当前作用域没有往上一级作用域查找,一直到最外层,如果都找不到则是is not define
13.定时器的分类?他们的区别及用法是什么?
Js中有两种定时器:
setInterval:间歇执行,setTimeout:延迟执行
setInterval(函数,时间) 时间单位ms,
语法:setInterval(function(){},1000); 隔一秒执行函数一次
一般用于倒计时,轮播图
setTimeout(函数,时间) 时间单位ms,
语法:setTimeout(function(){},1000); 延迟一秒执行函数一次,只会执行一次
一般用于广告,广告弹出层
14.把下面的字符串去重,并去除掉特殊字符按照数字在前字母在后的顺序排序字符串
如下:“1233fddfd&3434fdsaff&454545&4545444rfdsfds&545gdsgs”
var str = “1233fddfd&3434fdsaff&454545&4545444rfdsfds&545gdsgs”;
var n = “”;
var s="";
for(var i=0;i<str.length;i++){
if((str[i]>=0&&str[i]<=9)&&n.indexOf(str[i])==-1){
n+=str[i];
}else if((str.charCodeAt(i)>=97&&str.charCodeAt(i)<=122)&&s.indexOf(str[i]) == -1){
s+=str[i];
}
}
console.log(n+s); //12345fdsarg
15.截取字符串“abcdefg”中的def。
var str = “abcdefg”;
if(str.indexOf(“def”)!=-1){
console.log(str.substr(str.indexOf(“def”),3));
}
16.数组方法pop() push() unshift() shift()?
push:在数组末尾添加一个或多个元素,返回当前数组下标
Pop:在数组末尾删除一个元素,返回被删除的元素
unshift:在数组的头部添加或删除元素,返回当前数组下标
shift:在数组头部删除一个元素,返回被删除的元素
17.split() join() 的区别?
split是字符串的方法,将字符串按照特定标志分割成数组
例:“u&s”.split(“&”) ------ [“u”,”s”] Join:是数组方法,将数组按标志组合成字符串 [“u”,”s”].join(“-”)–‘u-s’
18.编写一个数组去重的方法。
function sort(arr) {
for(var i = 0;i<arr.length;i++){
for(var j = i+1;j<arr.length;j++){
if(arr[i] == arr[j]){
arr.splice(j,1);
j–; //删除一个元素后,后面的元素会依次往前,下标也需要依次往前
}
}
}
return arr
}
19.冒泡算法排序?
for(var i = 0;i<arr.length;i++){
for(var j = 0;j<arr.length-i;j++){
if(arr[j] > arr[j+1]){ //
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
20.DOM怎样添加、移除、移动、复制、创建和查找节点
获取子节点
父节点.children
父节点.childNodes
获取父节点
子节点.parentNode
子节点.offsetParent
创建
document.createElement(‘标签名’)
document.createTextNode(‘文本内容’)
添加
父节点.appendChild(子节点)
父节点.insertBefore(newChild,refChild)
复制
被复制的节点.cloneNode(true)
删除:
节点.remove()
父节点.removeChild(子节点)
替换
父节点.replaceChild(newChild,refChild)
21.什么是window对象? 什么是document对象?
window是js中最大的对象,表示窗口,包含document
document文档对象,表示HTML
22.offsetWidth、clientWidth、scrollTop的区别?
offsetWidth:占位宽,包含 内容宽+左右padding+左右border
clientWidth:可视宽,包含 内容宽+左右padding
scrollTop:页面被卷去的高
23.如何获取url地址中搜索内容?
window.location.search
24.事件、IE与火狐的事件机制有什么区别?
IE的事件流是冒泡流,而火狐同时支持冒泡流和捕获流。
25.事件绑定和普通事件有什么区别。
标签.事件:如果给同一个元素添加同一个事件,后面的会覆盖前面 事件绑定:可以给同一个元素添加同一个事件,不会被覆盖
26.解释一下事件流?
事件捕获阶段:当事件发生的时候,将事件从window依次往子元素传递 确定目标阶段:确定事件目标 事件冒泡阶段:事件目标开始处理事件,处理完以后会将事件依次传递给父元素,一直到window 事件都是在事件冒泡处理,ie只有冒泡
27.拖拽效果中有几种事件?
按下onmousedown,拖拽onmousemove,弹起onmouseup
28.cookie的利弊?
优点:极高的扩展性和可用性
1.通过良好的编程,控制保存在cookie中的session对象的大小。
2.通过加密和安全传输技术(SSL),减少cookie被破解的可能性。
3.只在cookie中存放不敏感数据,即使被盗也不会有重大损失。
4.控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie。
缺点:
1.Cookie数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。
2.安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
3.有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。
因为这些弊端(主要是cookie的大小和多少都受限制,并且每次你请求一个新的页面的时候Cookie都会被发送过去,这样无形中浪费了带宽,另外cookie还需要指定作用域,不可以跨域调用),IE8以后,就出现一个web storage;它仅仅是为了本地缓存数据而存在;但是Cookie也是不可以或缺的:Cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在。
29.call()和apply()的区别和作用?
都是用来改变this的指向,在传值的过程中会有些区别
call(this的指向,参数1,参数2…)
apply(this的指向,[参数1,参数2…])
30.创建ajax的过程。
function ajax(json) {
json.data = json.data||""; //如果没有请求参数,为空
json.contentType = json.contentType || “application/x-www-form-urlencoded”; //如果没有字符编码,用默认的
//1.创建对象
if(window.XMLHttpRequest){ //正常
var ajax = new XMLHttpRequest();
}else { //兼容ie6
var ajax = new ActiveXObject(“Microsoft.XMLHTTP”);
}
//2.建立连接
if(json.type.toUpperCase() ==“get”.toUpperCase()){
ajax.open(“GET”,json.url+"?"+json.data,true);
//3.发送请求
ajax.send();
}else {
ajax.open(“POST”,json.url,true);
//3.设置请求头 ajax.setRequestHeader(“Content-type”,json.contentType+";charset=utf-8");
//4.发送请求
ajax.send(json.data);
}
//4.监听结果
ajax.onreadystatechange = function () {
if(ajax.readyState == 4){
if(ajax.status == 200){
json.success(ajax.response);
}
}
}
}
31.ajax请求的时候get 和post方式的区别,什么时候用post。
GET请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给WEB服务器。当然在Ajax请求中,这种区别对用户是不可见的
GEt传输数据容量小,不安全,post传输数据内容大,更加安全;当向服务器发送一些数据的时候选择post比较安全
32.ajax请求时,如何解释json数据。
如果是字符串形式的json:eval("("+ajax.response+")")
如果是本地的json文件:JSON.parse(data)
33.同步和异步的区别?
异步:客户端与服务器请求数据的过程中,可以做其他的事情
同步:客户端与服务器请求数据的过程中,不能做其他的事情
34.常见的http状态码?
不需要知道全部,常见的就可以,比如200 404 503
200状态码:
表示请求已成功,请求所希望的响应头或数据体将随此响应返回
201状态码:
表示请求成功并且服务器创建了新的资源,且其 URI 已经随Location 头信息返回。假如需要的资源无法及时建立的话,应当返回 ‘202 Accepted’
202状态码:
服务器已接受请求,但尚未处理
301状态码:
被请求的资源已永久移动到新位置。服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302状态码:
请求的资源临时从不同的URI响应请求,但请求者应继续使用原有位置来进行以后的请求
304自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。如果网页自请求者上次请求后再也没有更改过,您应将服务器配置为返回此响应(称为 If-Modified-Since HTTP 标头)。
301状态码:
被请求的资源已永久移动到新位置。服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302状态码:
请求的资源临时从不同的URI响应请求,但请求者应继续使用原有位置来进行以后的请求 304自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。如果网页自请求者上次请求后再也没有更改过,您应将服务器配置为返回此响应(称为 If-Modified-Since HTTP 标头)。
401状态码:
请求要求身份验证。对于需要登录的网页,服务器可能返回此响应。
403状态码:
服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。
404状态码:
请求失败,请求所希望得到的资源未被在服务器上发现。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。
500状态码:
服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器的程序码出错时出现。
503状态码:
由于临时的服务器维护或者过载,服务器当前无法处理请求。通常,这个是暂时状态,一段时间会恢复
35.js哪些操作会造成内存泄露?
1)意外的全局变量引起的内存泄露 function leak(){ leak=“xxx”;//leak成为一个全局变量,不会被回收 }
2)被遗忘的定时器或者回调
3)闭包引起的内存泄漏
36.$(document).ready() 方法和window.onload 有什么区别?
window.onload与ready的区别
1.window.onload会覆盖之前的ready的区别,不会覆盖,会叠加
2.window.onload等文档和资源都加载完成以后调用ready只要文档加载完成以后就会调用
37.怎么解决跨域问题?
通过jsonp解决跨域,即通过script标签的src属性引入一个js文件,通过回调函数将数据返回 KaTeX parse error: Expected 'EOF', got '&' at position 34: …script src=’url&̲callback=showDa….ajax()方法中,只需配置一个dataType:‘jsonp’,就可以发起一个跨域请求 。
▼
原创系列推荐
▼
5. Webpack4 入门(上)|| Webpack4 入门(下)
6. MobX 入门(上) || MobX 入门(下)
7. 59篇原创系列汇总
回复“加群”与大佬们一起交流学习~
点这,与大家一起分享本文吧