js高频面试题,整理好咯

中级前端面试题,不低于12k,整理的是js较高频知识点,可能不够完善,你们有兴趣能够留言补充,我会逐步完善,若发现哪里有错,还请多多斧正,哈哈前端

http和浏览器相关知识点,已分离出,会在下篇整理程序员

 黑寡妇

 

 

数据类型es6

基本类型:Number,String,Boolean,Null,Undefined面试

引用类型:Array,Function算法

 

基本类型和引用类型的区别数组

引用类型值保存在堆里,基本类型是存放在栈里浏览器

引用类型值可添加属性和方法,而基本类型值则不能够缓存

 

判断类型方式安全

  1. typeof
  2. instanceof
  3. Object.prototype.toString.call()

 

栈和堆的区别闭包

  1. 栈由编译器自动分配释放空间,堆通常由程序员分配释放
  2. 栈存放在一级缓存中,调用完毕当即释放;堆则是在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定

 

数组经常使用方法

改变原数组

  1. shift:删除第一个元素
  2. unshift:向数组开头添加元素
  3. pop:删除最后一个元素
  4. push:向数组末尾添加元素
  5. reverse:数组倒序排序
  6. sort:数组正序排序
  7. splice: splice(start,length,item)删,增,替换数组元素

不改变原数组

  1. concat:链接多个数组
  2. join:将数组全部元素以字符分隔
  3. slice:slice(start,end),切割数组
  4. map,filter,some,every等不改变原数组

 

数组排序

  1.  reverse()倒序
  2. sort()正序
  3. 冒泡排序
var arr = [1, 9, 4, 50, 49, 6, 3, 2];

function test(){

for (var i = 0; i < arr.length - 1; i++){

for (var j = i + 1; j < arr.length; j++){

var tempi = arr[i]; // 获取第一个值,并与后一个值比较

var tempj = arr[j];

      if (tempi > tempj){

        arr[i] = tempj;

        arr[j] = tempi; // 若是前一个值比后一个值大,那么相互交换

      }

    }

}

console.log(arr); // return arr

}

test(arr);  // [1, 2, 3, 4, 6, 9, 49, 50]

 

 

数组去重

  1. indexOf()  用for循环遍历数组,把等于-1的值push进新建的空数组里
  2. es6的set()方法
var arr = [1,1,12,12,13,13,8,8,9,7,5];

var arr2 = [...new Set(arr)]; // [1, 12, 13, 8, 9, 7, 5]

 

 

浅拷贝与深拷贝

深拷贝和浅拷贝只针引用类型(Object、Array)的数据

拷贝只复制指向某个对象的指针,而不复制对象自己,新旧对象共享同一内存,修改新对象会改变原对象

深拷贝则另外创造个如出一辙的对象,新旧对象不共享内存,修改新对象不会改到原对象

浅拷贝实现方法

  1. Object.assign() // 注意,当object只有一层结构,是深拷贝
  2. Array.prototype.concat()
  3. Array.prototype.slice()

深拷贝实现方法

  1. JSON.parse(JSON.stringify())
  2. 递归法,for循环遍历对象、数组直到里边都是基本数据类型,而后再去复制

 

JSON.stringify()实现深拷贝的缺点

  1. 如obj里有时间对象,则JSON.stringify(序列化)再JSON.parse(反序列化)后,时间对象将变成字符串形式,而不是对象形式
  2. 如obj里有正则(RegExp)、Error对象,则序列化后只获得空对象
  3. 如obj里有函数,undefined,则序列化后会丢失
  4. 如obj里有NaN、正无穷(Infinity)和负无穷(-Infinity),则序列化后会变成null

 

null,undefined的区别
null用来表示还没有存在的对象

undefined表示"缺乏值",就是此处应该有一个值,可是尚未定义

 

函数声明与函数表达式

在js中,解析器会率先读取函数声明,并使其在执行任何代码前可用(可访问)

而函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解析执行

 

原型链

函数对象

在JS中,函数即对象

原型对象 

定义函数对象时,会包含一个预约义属性prototype,称为原型对象

__proto__

建立对象时,会有个[[proto]]内置属性,用于指向建立它的函数对象的prototype,prototype也有[[proto]]属性,在不断指向中,造成了原型链

 

原型链的终点

原型链终点是null

 

原型链终点为何是null

原型链上全部节点都是对象,不能是字符串、数字、布尔值等原始类型

另外,规范要求原型链必须是有限长度

 

new操做符具体作了什么

  1. 建立空对象,this引用该对象,同时继承该对象的原型
  2. 属性和方法被加入到this引用的对象中

 

this指向问题

当没有被对象调用时,指向window

当被对象调用时,指向调用他的对象

当实例化对象就在对象中时,指向该实例化对象

 

判断空对象方法

  1. JSON.stringify(obj)

// 判断JSON.stringify(data) == "{}"

  2. Object.keys(obj)

// 返回自身的可枚举属性

// 判断Object.keys(data).length === 0

 

闭包

闭包就是可以读取其余函数内部变量的函数

 

闭包优势

  1. 将变量长期保存,不被垃圾回收机制回收
  2. 避免全局变量的污染
  3. 安全性提升

 

闭包缺点

容易形成内存泄漏

 

闭包应用场景

  1. 封装私有变量
  2. 经过闭包实现setTimeout传参
  3. 做为回调函数绑定到事件

 

常见内存泄漏

  1. 闭包
  2. 全局变量,至关于挂载到 window 对象上
  3. 被遗忘的定时器和回调函数

 

垃圾回收机制

  1. 标记清除
  2. 引用计数

 

事件冒泡

当元素接收事件时,会把接收的事件传递给本身的父级,层层传递直到window

 

阻止事件冒泡

IE浏览器: e.cancelBubble = true

其余: e.stopPropagation()

 

事件捕获

用addEventListener监听目标元素事件

 

阻止默认事件

  1. return false
  2. ev.preventDefault()

 

事件委托原理,及优缺点

原理为事件冒泡机制

优势

  1. 可大量节省内存占用,减小事件注册
  2. 可实现当新增子对象时,无需再对其事件绑定,对于动态内容部分尤其合适

缺点

可能会出现事件误判,把本不该用触发事件的被绑上了事件

 

事件循环

Javascriprt为单线程。单线程的缺点是全部任务需排队,后一个任务要等前一个任务执行完毕,这样耗时过久,因而js全部任务分为两种:同步任务,异步任务

JS引擎将全部任务按类添加到宏任务、微任务两个队列,首先在宏任务队列中取出第一个任务,执行完毕后,再把微任务队列中全部任务按序执行完,以后再取宏任务,周而复始,直至两个队列的任务都取完,过程就叫事件循环

 

宏任务和微任务

宏任务:setTimeout,setInterval

微任务:Promise,process.nextTick

相关文章
相关标签/搜索