js面试常问问题含详细答案

186 阅读8分钟

1、前++、后++、区别?

var i=2 ;
a = i++ //将i的值赋给a , 即a = i,之后再执行i = i + 1;   2
a = ++i //将i+1 的值赋给a,即a = i + 1 ,之后再执行i = i + 1;   3
console.log(a)
复制代码

【总结】:

前++是先自加后计算、后++是后自加先计算

1:前置++ 是将自身+1 后的值赋给变量,同时自身加1;

2:后置++ 是将自身的值赋给变量,之后自身再加1;

2、JS 有哪些数据类型?

Js基本数据类型 undefined null boolean number string bigint
Js引用类型 object Array function
ES6基本数据类型 多了个symbol

3、js判断类型?

1、typeof
检测不出null 和 数组,结果都为object,所以typeof常用于检测基本类型
2、instanceof
不能检测出number、boolean、string、undefined、null、symbol类型,所以instancof常用于检测复杂类型以及级成关系
3、constructor
null、undefined没有construstor方法,因此constructor不能判断undefined和null。但是contructor的指向是可以被改变,所以不安全
4、Object.prototype.toString.call
全类型都可以判断

4、数据类型怎么检测?

1typeof
例:console.log(typeof true) // boolean

2instanceof
例:console.log([1,2] instanceof Array) // true

3、constructor
例: console.log([1, 2].constructor === Array) // ture

4Object.prototype.toString.call
例:Object.prototype.toString.call([1, 2]) // [object Array]
复制代码

5、Js数组的方法

join()数组转换成字符串
push()尾部添加
pop()尾部删除
shift() 头部删除
unshift() 头部添加
sort()排序
reverse()反转
concat()链接两个或多个数组
slice()
var arr=[1,2,3,4,5]
console.log(arr.slice(1)) //[2,3,4,5]选择序列号从1到最后的所有元素组成的新数组
console.log(arr.slice(1,3)) //[2,3]不包含序列号,序号为3的元素
splice()
splice(index,howmany,item1,...itemx)
index参数:必须,整数,规定添加或删除的位置,使用负数,从数组尾部规定位置
howmany参数:必须,要删除的数量,如果为0则不删除项目
item1,...itemx参数:可选,向数组添加的新项目
var arr=[1,2,3,4,5]
console.log(arr.splice(2,1,"hello"));//[3]返回的新数组
console.log(arr);//[1,2,"hello",4,5]
indexOf()和 lastIndexOf() (ES5新增)
forEach() (ES5新增)
map() (ES5新增)
filter() (ES5新增)
every() (ES5新增)
some() (ES5新增)
reduce()和 reduceRight() (ES5新增)

6、JS中的Array.splice()和Array.slice()方法有什么区别?

话不多说,来看第一个例子:

var arr=[0,1,2,3,4,5,6,7,8,9];//设置一个数组
console.log(arr.slice(2,7));//2,3,4,5,6
console.log(arr.splice(2,7));//2,3,4,5,6,7,8
//由此我们简单推测数量两个函数参数的意义,
slice(start,end)第一个参数表示开始位置,第二个表示截取到的位置(不包含该位置)
splice(start,length)第一个参数开始位置,第二个参数截取长度
复制代码

接着看第二个:

var x=y=[0,1,2,3,4,5,6,7,8,9]
console.log(x.slice(2,5));//2,3,4
console.log(x);[0,1,2,3,4,5,6,7,8,9]原数组并未改变
//接下来用同样方式测试splice
console.log(y.splice(2,5));//2,3,4,5,6
console.log(y);//[0,1,7,8,9]显示原数组中的数值被剔除掉了
复制代码

slice和splice虽然都是对于数组对象进行截取,但是二者还是存在明显区别,函数参数上slice和splice第一个参数都是截取开始位置,slice第二个参数是截取的结束位置(不包含),而splice第二个参数(表示这个从开始位置截取的长度),slice不会对原数组产生变化,而splice会直接剔除原数组中的截取数据!
slice不会改变原数组,splice会改变原数组

7、数值转换

JSON.parse() 转json对象
JSON.stringify() 转json字符串
String(),toString() 转字符串类型
Number parseInt()字符串转数值类型
split 字符串转数组
join 数组转字符串

8、什么是跨域,常见跨域

由于浏览器获取数据遵循同源策略,所以当访问非同源资源的时候,就需要跨域,常见的跨域方式有jsonp,a img src cors
同源策略:同协议,端口,域名的安全策略
jsonp原理
动态创建script标签,利用callpack回调函数获取值

function callbackFunction(){
  alert("回滚");
}
var script=document.createElement("script");
script.src="http://frergeoip.net.json/?callback=callbackFunction";
复制代码

CORS的原理
当传输数据量比较大,get形式搞不定的时候,可以用到cors跨域,cors原理是定义一种跨域访问的机制,可以让ajax实现跨域访问。Cors允许一个域上的网络应用向另一个域提交跨域ajax请求。实现此功能非常简单,只需由服务器发送一个响应标头即可。 Jsonp是get形式,承载的信息量有限,所以信息量较大的时cors是不二选择。

9、http协议:

http协议是定义服务器端和客户端之间文件传输的沟通方式
请求服务器上的资源,请求html css js 图片文件等
请求方法(所有方法全为大写)有多种,各个方法的解释如下:
GET (get) 请求获取Request-URI所标识的资源 --获取资源
POST (post) 在Request-URI所标识的资源后附加新的数据 ---传输资源
HEAD (head) 请求获取由Request-URI所标识的资源的响应消息报头 ---获取报文首部
PUT (put) 请求服务器存储一个资源,并用Request-URI作为其标识 ---更新资源
DELETE (delete) 请求服务器删除Request-URI所标识的资源 ---删除资源
TRACE (trace) 请求服务器回送收到的请求信息,主要用于测试或诊断
CONNECT(connect) 保留将来使用
OPTIONS(options) 请求查询服务器的性能,或者查询与资源相关的选项和需求
常见状态码:
200 请求成功
301 资源(网页等)被永久转移到其他url
404 请求的资源不存在
500 内部服务器错误

10、HTTP状态码

100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息
200 OK 正常返回信息
201 Created 请求成功并且服务器创建了新的资源
202 Accepted 服务器已接受请求,但尚未处理
301 Moved Permanently 请求的网页已永久移动到新位置。
302 Found 临时性重定向。
303 See Other 临时性重定向,且总是使用 GET 请求新的 URI。
304 Not Modified 自从上次请求后,请求的网页未修改过。
400 Bad Request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。
401 Unauthorized 请求未授权。
403 Forbidden 禁止访问。
404 Not Found 找不到如何与 URI 相匹配的资源。
500 Internal Server Error 最常见的服务器端错误。
503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。

11、说说你对闭包的理解?

使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
闭包有三个特性:
1.函数嵌套函数
2.函数内部可以引用外部的参数和变量
3.参数和变量不会被垃圾回收机制回收
闭包用途
1缓存
设想我们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,那么我们就需要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,如果找不到,则进行计算,然后更新缓存并返回值,如果找到了,直接返回查找到的值即可。闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。
2 实现封装
可以先来看一个关于封装的例子,在person之外的地方无法访问其内部的变量,而通过提供闭包的形式来访问:

var person = function(){    
    //变量作用域为函数内部,外部无法访问    
    var name = "default";              
    return {    
       getName : function(){    
           return name;    
       },    
       setName : function(newName){    
           name = newName;    
       }    
    }    
}();        
print(person.name);//直接访问,结果为undefined    
print(person.getName());    
person.setName("abruzzi");    
print(person.getName()); 
复制代码

12、如何阻止事件冒泡?

ie:阻止冒泡ev.cancelBubble = true;
非IE ev.stopPropagation();

13、如何阻止默认事件?

(1)return false;(2) ev.preventDefault();

14、事件代理

事件代理是指,对父盒子绑定事件,然后子盒子触发事件,由于产生事件冒泡,导致父盒子事件也被触发,此时,在父盒子的时间处理函数中,可以通过srcElement或者target属性来获取目标时间,并对其进行相应的处理

15、添加 删除 替换 插入到某个节点的方法?

1)创建新节点
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
 
2)添加、移除、替换、插入
appendChild() //添加
removeChild() //移除
replaceChild() //替换
insertBefore() //插入
 
3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
复制代码

16、document load 和document ready的区别?

document.onload 是在结构和样式,外部js以及图片加载完才执行js
document.ready是dom树创建完成就执行的方法,原生种没有这个方法,jquery中有 $().ready(function)