前端js面试题总结
一、slice()与splice()的用法和区别
1. slice(start,end)
从start开始截取到end但是不包括end
返回值为截取出来的元素的集合
原始的数组不会发生变化
2. splice(start,deleteCount,item1,item2…..)
start参数 开始的位置
deleteCount 要截取的个数
后面的items为要添加的元素
如果deleteCount为0,则表示不删除元素,从start位置开始添加后面的几个元素到原始的数组里面
返回值为由被删除的元素组成的一个数组。如果只删除了一个元素,则返回只包含一个元素的数组。如果没有删除元素,则返回空数组
这个方法会改变原始数组,数组的长度会发生变化
【ps】区别:slice返回值是截取出来元素的集合,不改变原数组,splice返回值是删除的元素,改变原数组
数组操作的方法扩展
1. push / pop 在数组末尾增/删元素;
2. unshift / shift 在数组首部增/删元素;
3. concat 把一个(或多个)数组和(或)值与原数组拼接,返回拼接后的数组
4. join() 把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔
5. reverse() 颠倒数组中元素的顺序
二、cookie跟session的区别联系
session与cookie的区别
(1)Cookie以文本文件格式存储在浏览器中,而session存储在服务端它存储了限制数据量。它只允许4kb它没有在cookie中保存多个变量。
(2)cookie的存储限制了数据量,只允许4KB,而session是无限量的
(3)我们可以轻松访问cookie值但是我们无法轻松访问会话值,因此它更安全
(4)设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。
总结:如果我们需要经常登录一个站点时,最好用cookie来保存信息,要不然每次登陆都特别麻烦,如果对于需要安全性高的站点以及控制数据的能力时需要用会话效果更佳,当然我们也可以结合两者,使网站按照我们的想法进行运行
三、cookie跟H5本地存储的区别
区别:
1. cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
2. cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下。存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
3. 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
4. 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。Web Storage 支持事件通知机制,可以将数据更新的通知发送给监听者。Web Storage 的 api 接口使用更方便。
四、es6新增了哪些新特性
1、let关键字,用来代替 var的关键字,特点: 1、变量不允许被重复定义 2、不会进行变量声明提升 3、保留块级作用域中i的
2、const定义常量,特点:1、常量值不允许被改变 2、不会进行变量声明提升
3、箭头函数(ps:this指向问题)
4、字符串模板``
5、ES6中字符串和数组新增方法
字符串
5-1-1、字符串模板
5-1-2、includes
5-1-3、startswith
5-1-4、endsWith 等
数组
5-2-1、Array.of //将一组数值转化为数组
5-2-2、Array.from (将伪数组转为数组: var list = Array.from(document.getElementsByTagName("li"));)
5-2-3、find() arr.find(function(value,index,arr){return value > 5;})
ps : 所谓的实例方法就是并不是以Array对象开始的,而是必须有一个已经存在的数组,然后使用的方法,这就是实例方法(不理解请看下边的代码)。这里的find方法是从数组中查找。在find方法中我们需要传入一个匿名函数,函数需要传入三个参数:
value:表示当前查找的值。
index:表示当前查找的数组索引。
arr:表示当前数组。
5-2-4、fill()等等 let arr=[0,1,2,3,4,5,6,7,8,9]; arr.fill('javascript',2,4);
ps: fill()也是一个实例方法,它的作用是把数组进行填充,它接收三个参数,第一个参数是填充的变量,第二个是开始填充的位置,第三个是填充到的位置。
五、call和apply的区别
答案:
Object.call(this,obj1,obj2,obj3)
Object.apply(this,arguments)
六、事件委托是什么
答案: 利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!
<ul id="ul1"> <li>111</li> <li>222</li> <li>333</li> <li>444</li> </ul>
window.onload = function(){ var oUl = document.getElementById("ul1"); oUl.onclick = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == 'li'){ alert(123); alert(target.innerHTML); } } }
七.、闭包是什么,有什么特性,对页面有什么影响
答案:闭包就是能够读取其他函数内部变量的函数,使得函数不被GC回收,如果过多使用闭包,容易导致内存泄露
八、js延迟加载的方式有哪些?
答案:defer和async、动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)、按需异步载入js
九、js数组快速排序
思路:
(1)在数据集之中,选择一个元素作为”基准”(pivot)。
(2)所有小于”基准”的元素,都移到”基准”的左边;所有大于”基准”的元素,都移到”基准”的右边。
(3)对”基准”左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
function quickSort(arr){ if (arr.length <= 1){return arr}; var pivotIndex = Math.floor(arr.length / 2); var pivot = arr.splice(pivotIndex,1)[0]; var left = []; var right = []; for (var i = 0; i < arr.length; i++){ if(arr[i] < pivot) { left.push(arr[i]); }else{ right.push(arr[i]); } } return quickSort(left).concat([pivot],quickSort(right)); }
十、js数组去重
方法一
思路:
1.创建一个新的数组存放结果
2.创建一个空对象
3.判断数组值是否已经保存在object中,未保存则push到新数组并用object[arrayItem]=1的方式记录保存
Array.prototype.unique3 = function(){ var res = []; var json = {}; for(var i = 0; i < this.length; i++){ if(!json[this[i]]){ res.push(this[i]); json[this[i]] = 1; } } return res; } var arr = [2,1,34,'你好',112,112,34,'你好','str']; console.log(arr.unique3()); //[2, 1, 112, 34, "你好", "str"]
方法二
思路:
1.构建一个新的数组存放结果
2.for循环中每次从原数组中取出一个元素,用这个元素循环与结果数组对比
3.若结果数组中没有该元素,则存到结果数组中
Array.prototype.unique1 = function(){ var n = []; //一个新的临时数组 for(var i = 0; i < this.length; i++) //遍历当前数组 { //如果当前数组的第i已经保存进了临时数组,那么跳过, //否则把当前项push到临时数组里面 if (n.indexOf(this[i]) == -1) n.push(this[i]); } return n; }
方法三、(es6)
1.function unique(arr) {
//通过Set对象,对数组去重,结果又返回一个Set对象
//通过from方法,将Set对象转为数组
return Array.from(new Set(arr))
}
2.[...new Set(arr)]
ps:个人比较推荐方法一跟方法三,es6为了兼容低版本浏览器可以考虑转es5
十一、js面向对象继承
1:拷贝继承
ps:继承父类的属性。我们采用call通过对象冒充的方式。让子类具有父类的属性。那么接下来我们所说的三种方式,都是针对父类的方法。更直接一点,就是父类prototype上的方法。
function Person(name,age){ this.name=name; this.age=age; } Person.prototype.eat=function(){ console.log("eat") } function Student(name,age,className){ Person.call(this,age,name) this.className=className } for(var attr in Person.prototype){ Student.prototype[attr]=Person.prototype[attr] } var s1=new Student(); console.log(s1.constructor) s1.eat(); --》eat
2:原型继承
ps:原型继承则是通过一个空函数来实现,也就是把父类的原型赋值给空函数,再把该空函数返回的一个实例对象等于子类的原型prototype属性
基本上分3步骤:
(1)var F = function(){};
(2)F.prototype = Parent.prototype;
(3)Child.prototype = new F();
还是通过上面的例子:
function Person(name,age){ this.name=name; this.age=age } Person.prototype.eat=function(){ console.log("eat") } function Student(name,age,className){ Person.call(this,name,age) this.className="two" } //继承方法 function inherit(subClass, superClass) { function F() {} F.prototype = superClass.prototype; subClass.prototype = new F(); subClass.prototype.constructor = subClass.constructor; } inherit(Student, Person); var s1=new Student("sean",20); s1.eat() //eat
3:es6继承,(es6中定义了类的概念,通过class关键字去申明一个类。写法简洁。但是这只是一个语法糖)
//定义一个person类 class Person{ constructor(name,age){ this.name=name; this.age=age } eat(){ console.log("eat") } } //子类Student继承person类 class Student extends Person{ constructor(name,age,className){ super(name,age) //super关键词用来继承父类的属性,相当于在es5中call的作用 this.className=className //子类新的属性 } test(){ console.log("考试") } } var p=new Person() var s=new Student("sean","24")console.log(s.name) ----》sean
十二、说出三种减低页面加载时间的方法
1、压缩css、js文件
2、合并js、css文件,减少http请求
3、外部js、css文件放在最底下
4、减少dom操作,尽可能用变量替代不必要的dom操作
还有js面试基础题,有兴趣的话可以看一下https://www.cnblogs.com/zwp06/p/9916007.html
浙公网安备 33010602011771号