JS面试基础

1.事件循环

JS是一门单线程的非阻塞的脚本语言,在执行任务的时候只有一个主线程来处理任务,其中,任务又分为同步任务和异步任务。
同步任务会直接进入主线程中执行,异步任务会存放在任务队列(Event Queue)中,
当主线程内的任务执行完毕后,就会读取任务队列(Event Queue)的任务,然后再主线程中执行,这个过程不断的重复,就形成了事件循环机制。
而在处理异步任务的时候,它们的执行优先级也是有区别的,异步任务又分为微任务和宏任务,
(常见的微任务Promise,宏任务定时器、I/O、UI 交互事件),异步任务在主线程中执行的时候,会先执行一个宏任务,然后执行所有的微任务。

2.闭包

闭包是一个函数,函数内保持上层作用域的引用,当函数在其定义的作用域外进行访问引用的数据,就产生闭包。通常所用的闭包是函数嵌套函数的形式,内部的那个函数通过return出来,然后内部的函数又保持对上层作用域的引用,而且内部函数还必须要在外部调用

优点:1.避免全局变量的污染  2.让变量常驻内存  3.将模块的公有属性和方法暴露出来

缺点:会造成内存泄露

3.ES6/ES7新特性

let和const:有块级作用,const值不可改变,模板字符串,数组跟对象可以解构赋值,对象字面量简写,for-of允许遍历获得键值,展开运算符,ES6箭头函数,Promise,set,map

ES7:includes(),查找一个值在不在数组里,若是存在则返回true,求幂运算符**

ES8:async异步函数 await等待异步操作的返回值

标签闭合、标签小写、不乱嵌套、提高搜索机器人搜索几率、使用外链css和js脚本、结构行为表现的分离、文件下载与  页面速度更快、内容能被更多的用户所访问、内容能被更广泛的设备所访问、更少的代码和组件,容易维护、改版方便,  不需要变动页面内容、提高网站易用性;

4.ajax:

1.创建一个xml对象  var xhr = new XMLHttpRequest();  ie下使用 var xhr = new ActiveXObject("Microsoft.XMLHTTP");  
2.调用xhr的open方法  xhr.open(method,url,true/false);//true表示异步,false表示  设置为同步  //method:请求方式  //url:接口路径  //true/false:ajax都是用来处理异步请求,一般不使用第三个参数  解决ie的缓存问题  xhr.open("GET","testhack.php?rand=" + new Date().getTime());  
3.调用send方法:发送请求  xhr.send();  请求方式为get时,直接调用xhr.send(null)即可 参数可以设置为null,也可不传参  请求方式为post时,在send前,需要先设置一个请求头  xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");  有数据传递  xhr.send(data);  如果无数据  xhr.send(null);  注意: 
4.ajax是一个异步的请求,请求是有一个过程的,回来的数据需要时间延迟一点就可以获取到了 
    setTimeout(function(){  console.log(xhr.responseText);  },500);

5.防抖节流:


function dithering(callBack,ms){  var t = null;  return function(){//这里是事件处理程序,事件对象在这里传递  
clearTimeout(t);  
var arg = arguments;//这个arguments是当前函数执行环境下的arguments  
t = setTimeout(function(){  callBack.apply(this,arg);  }.bind(this),ms);  }  
}

//函数节流 

 function throttle(callBack,ms){
 //有一个开始时间
 var startTime = new Date().getTime();
 return function(){
 //console.log(start);
 //在input中开始输入的时候 也有一个时间
 var nowTime = new Date().getTime();
 if(nowTime - startTime >= ms){//相差1秒时间来执行一次
 callBack.apply(this,arguments);
 startTime = nowTime;
 }
 }
 }

闭包实现函数去抖和节流
去抖使用setTimeout实现(在一个时间段内,如果高频触发,不执行结果,当触发停下来后,才去获取结果)
节流使用输入时间减去当前时间(节流:每隔一个时间段执行一次结果)

6.手写深复制:

function deepCopy(obj){  //排除非引用数据类型和函数 ,不是对象或是函数就直接返回  
if(!(obj instanceof Object) || typeof obj === "function") 
return obj;  //程序走这里包含了函数 数组 和对象  //[] {};  //如果obj不是数组,就一定是对象,  
//如果是数组newObj初始化为一个数组,反之为一个空对象,判断obj是数组还是对象  
var newObj = Array.isArray(obj) ? [] : {};  
//for in遍历  
for(var key in obj){  
newObj[key] = obj[key];  //判断obj[key]是否是一个数组或对象  
if(!!obj[key] && obj[key] instanceof Object){ 
 newObj[key] = deepCopy(obj[key]);  
}else{  newObj[key] = obj[key];  } 
 }  
return newObj;  }

7.继承:

继承完善: 
 function Father(name,age){  
this.name = name;  this.age = age;  
}  
Father.prototype = {  constructor : Father,  fn : function(){  console.log(this.name+"ok");  }  }  
function Son(name,age,phone){  //这里继承了实例  Father.call(this,name,age);  this.phone = phone;  } 
 //完善原型链继承  
Son.prototype = Object.create(Father.prototype); 
 Son.prototype.constructor = Son;

8.ES6继承:

 class Father{
 constructor(name){
 this.name = name;
 }
 init(){
 console.log(this.name+"ok");
 }
 } 
 class Son extends Father{ 
 constructor(name,age){
 super(name);  //如需继承父级就添加super方法;
 this.age = age;
 }
 init(){
 super.init(); 
 console.log("1");
 } 
 }; 
 var s = new Son("tom",19); 
 s.init();

9.三次挥手4次握手

10.vue和react的区别是什么

1.书写方面上vue提供了大量的api,需求功能实现起来代码量更少。react的api比较少,写法更接近原生的JS

2.数据响应上Vue通过 getter/setter劫持数据,精确知道数据变化;React是用新的数据替换旧的数据,通过diff运算监听数据变化的

3.组件复用Vue是通过mixin,React通过HoC( 高阶组件)

4.React是通过JSX渲染模板。而Vue是通过一种拓展的HTML语法进行渲染

5.diff运算上vue是边对比边更新DOM的,react是先存放在diff运算队列中,然后一次性批量更新DOM
11.垃圾回收机制/内存泄漏

局部变量会在堆或栈上被分配相应的空间以存储它们的值,函数执行结束,这些局部变量也不再被使用,它们所占用的空间也就被释放,如果局部变量被函数外部的变量所使用,无法被释放。
12.react-redux

单页面需求的越来越复杂,为了解决这个问题就需要用到状态管理工具,而redux是react的状态管理工具,redux有三个核心概念 Action,Reducer,Store,Action是一个JavaScript对象,由于State 是只读的,要想更新 state 中的数据,你需要发起一个 action。State使用纯函数来执行修改,Reducer是一个纯函数,它接收Action和State作为参数,深复制state的数据,使用switch条件判断,返回新的数据。redux的原则是单一数据源的,Store就是数据保存的地方,整个应用中只能有一个Store
13.key作用

key给每一个元素提供了唯一的类似id的属性,依靠这个key可以diff运算会更快速更准确的对比新旧虚拟DOM,提高性能
14.AMD、CMD、commonJS:

[CommonJs](http://javascript.ruanyifeng.com/nodejs/commonjs.html) 是服务器端模块的规范,require加载模块是同步的

AMD异步加载模块,require第一个参数[module]是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数

CMD 可以按需加载,依赖就近
15.JS优化:

减少HTTP请求次数,使用浏览器缓存、减少DOM操作(如使用innerHTML代替)、缓存DOM操作的结果减少IO读取操作、当设置样式比较多时,设置classname来操作、图片预加载、避免使用table,可用div+css布局
16.diff计算:fran
17.nodejs:

是一个 Javascript 运行环境,简单的说 Node.js就是运行在服务端的 JavaScript。它有一个很棒的包管理系统NPM。通过运行“npm install 包名”几乎可以安装任何包/库,在开发工作中为你提供各种便利
18.WebPack: https://www.cnblogs.com/laneyfu/p/6252307.html

可以看做是模块打包机:它做的事情是,分析你的项目结构,找到 JavaScript 模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用

使用优化:区分开发及生产环境、使用代码热替换、将模块暴露到全局、合并公共代码、善用alias
19.Git:

是一个开源的分布式版本控制系统,可以有效、高速的处理从很小到非常大的项目版本管理。
20.react优化:

遍历列表使用key,使diff算法更好的复用`dom`元素

减少节点的嵌套,减少`diff`算法的计算量

精简state,需要响应式的数据才存入`state`

减少使用CSS内联样式

多用三元表达式

代码分割

减少子组件的render重新渲染,使用Memo
21.项目难点:

1.前端权限的实现,必须要后端提供数据支持

2.权限的数据需要在多组件之间共享,因此使用状态管理

在角色权限验证的时候,虽然是后端来验证实现的,但是为了降低非法操作,减轻服务器压力,提高用户体验,一般在前端渲染的时候进行优化,在菜单动态获取上,就需要根据后端返回数据的支持,展示相应的菜单。对界面的控制上如果用户没有登录,就需要跳转到登录页面,如果已经登录的用户,在地址栏输入跳转到权限不够的地址,就需要跳转到404界面。在页面按钮的控制中,根据权限数据,展示可进行操作的按钮,比如增删查改。减少请求的数据,可能会有用户通过浏览器的调试工具,把某些禁用的按钮变成启用的状态,这时候发送的请求就需要被拦截下来。

实现思路:

手动将按钮禁用状态进行修改,减少http请求: 根据后端返回字段,判断有没有权限去修改

用户没有登录拦截:判断有没有token,如果没有就使用编程式路由进行跳转

跳转到权限不够的地址:根据权限,对路由规则进行动态添加,匹配不到就重定向或者跳转到404界面

展示可进行操作的按钮:判断权限对按钮进行隐藏

响应拦截: 如果token被修改,根据后端返回提示错误的数据,对页面尽心重新登录

你可能感兴趣的:(JS面试基础)