前端面试题集合,持续更新中(附答案,简单易懂)

最近面试遇到的一些问题以及平时的一些积累,如有错误,欢迎指正O(∩_∩)O~~。

http和https的区别

HTTP协议:超文本传输协议,英文是Hyper Text Transfer Protocol,它是从服务器传输超文本标记语言(HTML)到本地浏览器的传送协议,基于TCP/IP通信协议来传递数据,端口号是80。
优点:
1.简单快速,客户端向服务器请求服务时,只用传递请求方法(get、post)和路径,通信速度快。
2.无连接,服务器处理完客户端的请求后就断开连接。
3.无状态,服务器断开后无任何记录,可以减轻服务器的负担。
缺点:
1.它是明文传输,各种账号、密码等信息通过http协议传输隐私信息非常不安全。
2.加入购物车,支付,登录。每次都需要验证身份信息,但是无状态所以无法连续。解决办法,就是cookie技术。
HTTPS协议:HTTP+SSL,通过SSL证书来验证服务器的身份,并为浏览器和服务器之间的通信进行加密,端口号是443。

ssl的加密算法

非对称加密、对称加密、散列算法
在这里插入图片描述
在这里插入图片描述

WebSocket与HTTP的联系?

相同点:
都是一样基于TCP的,都是可靠性传输协议。
都是应用层协议。
不同点:
WebSocket是双向通信协议,可以双向发送或接受信息,实时通信。HTTP是单向的,只能一个request对应一个response。
websocket 是有状态的,http 是无状态的。

输入www.baidu.com并按下回车,中间发生了什么?

1、 浏览器先尝试从Host文件中获取该请求对应的服务器IP地址,如果没有找到,就使用DNS域名解析服务器来解析IP地址。(一个域名可能对应多个ip地址)
2、 根据IP地址,建立TCP连接3次握手。(第三次发送一个确认报文,防止出现失效的连接请求被服务端接收的情况,从而产生错误)
3、 发送HTTP请求。
4、收到服务器的响应,浏览器解析HTML文本,构建DOM树,解析css,构建样式树,加载js,两者合成render(渲染)树,最后渲染在页面上。

浏览器渲染HTML的过程?

1、html被html解析器解析成DOM元素,css被css解析器解析为CSSOM树。
2、DOM树和CSSOM树合成形成Render树。
3、渲染树上的每个节点信息(确定位置和大小)重排,这个过程叫做Reflow。
4、最后页面渲染重绘(Repaint)呈现出来。
减少重排:用事件捕获减少DOM操作、js addClass而不是操作style、动画元素设置成absolute或者fixed,这样不会影响到其他元素、opcity代替display:none,transform代替top。

$(document).ready() 与window.onload的区别?

$(document).ready:意思就是DOM树加载完毕,就执行,不必等到页面中图片或其他外部文件都加载完毕。并且可以写多个.ready。
window.onload:是页面所有元素都加载完毕,包括图片、视频、js等所有元素。只能执行一次。

谈谈你对闭包的理解

使用闭包主要是为了封装私有的方法和变量,闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,使用不当容易造成内存泄漏。
即:函数 A 返回了一个函数 B,并且函数 B 中使用了函数 A 的变量,函数 B 就被称为闭包。

function outer() {
    var a = 1;
    return function() {
        return a
    }
}
var b = outer();
console.log(b());  // 1

闭包有三个特性:
1、函数嵌套函数;
2、函数内部可以引用外部的参数和变量;
3、参数和变量不会被垃圾回收机制回收;
清除:把变量或者函数设为null。

清除浮动的几种方式?

1、浮动的元素后面加一个空div,设为clear:both;
2、父元素overflow:hidden或zoom:1;
3、父元素设置高度
4、父元素:

.div:after(伪类){
    height: 0;
    clear: both;
    content: '.';
    visibility: hidden;
    zoom: 1;    //兼容IE
}

webpack和gulp的区别

1、 webpack是前端资源模块的管理和打包工具,gulp是规范前端开发流程的工具。
2、webpack文档资源文件的处理是通过入口文件产生的依赖形成的,gulp是配置不同的task,对该task配置路径下的所有资源都可以管理。

npm install、npm install --save与npm install --save-dev区别?
npm install moduleName //安装模块到文件node_modules目录下
npm install --save moduleName //将模块安装到文件node_modules目录下,并在package文件的dependencies节点写入依赖。
npm install --save-dev moduleName //将模块安装到文件node_modules目录下,并在package文件的devDependencies节点写入依赖。

如何判断一个变量是不是数组?

1、使用Array.isArray()判断,如果返回true,说明是数组;

Array.isArray([1,2,3]);    //true
Array.isArray(arguments);   //false   arguments是类数组,不是数组。

2、使用instanceof判断,如果返回true,说明是数组;

[1,2,3] instanceof Array;    //true

3、使用Object.prototype.toString.call()判断,如果值是"[object Array]“,说明是数组,如果值是”[object Object]",说明是对象;还可以用来准确判断number、string、boolean、function等

Object.prototype.toString.call([1,2,3]);    //[object Array]

4、通过constructor来判断,如果是数组,那么arr.constructor===Array(不准确,因为可以更改值);

例:
var arr = [1,2,3];  
arr.constructor===Array;    //true
arr.constructor = Object;
 arr.constructor===Array;    //false
 
例:
function fn(){
    console.log(arguments.constructor===Array);  //false
    arguments.constructor=Array;
    console.log(arguments.constructor===Array);  //true
}
fn(1,2,3);

谈谈你对JS执行上下文和作用域链的理解

执行上下文就是当前js代码被解析和执行时所在环境,函数每调用一次,都会产生一个新的执行环境,因为不同的调用可能就有不同的参数。

function fn(x) {
  console.log(arguments)
  console.log(x)
}
fn(20);
fn(10);

作用域是一个‘地盘’,作用域是静态观念的,而执行上下文环境是动态的,有闭包存在时,一个作用域存在两个上下文环境也是有的。

let x = 100;          // 全局作用域
function fn(x) {     // fn作用域 
   return function bar() {     // bar作用域
      console.log(x)
    }
}
let f1 = fn(5);
let f2 = fn(10);
f1() // 5
f2() // 10

同一个作用域下,对同一个函数的不同调用会产生不同的执行上下文环境,继而产生不同的变量的值,所以,作用域变量的值是在执行过程中确定的,而作用域是在函数创建时就确定的

let a = 100
function fn() {
   let b = 20
   return function bar() {
     console.log(a + b);
   }
}
let x = fn();
b = 200
x()     //120

bar的这个作用域中没有a和b的值,它就会向上找到fn的作用域取得b的值,再向上全局作用域找到a的值,找到了就结束了,这就是作用域链

js的常见错误类型

1、 SyntaxError (语法错误)
eg:var 1a;
2、Reference (引用错误)
eg:console.log(a); let a=1;
3、TypeError(类型错误)
eg:var a=new 123;
4、RangeError(范围错误)
eg:var a=new Array(-1); //超出有效范围

谈谈你对promise的理解

promise是处理异步操作的一种解决方案。
promise对象有三个状态:pending、fulfilled、rejected,异步操作的结果是由pending变成fulfilled成功或变成rejected失败。
promise构造函数接受一个函数作为参数,以及该函数的两个参数分别为resolve和reject两个函数。

const promise = new Promise(function(resolve, reject){
    if(true){
        resolve(1);
    }else{
         reject(2);
    }
})

分别对应promise对象的then()和catch()方法。

promise.then(function(value){
    console.log(value);
}).catch(function(error){
    console.log(error)
});

**Promise.all()**方法用于将多个Promise实例,包装成一个新的Promise实例。

const p=Promise.all([p1,p2,p3]);

注:a、只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
b、只要p1、p2、p3之中有一个变成rejected,p的状态就会变成rejected,此时第一个变成reject的实例的返回值,会传递给p的回调函数

Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.race([p1, p2, p3]);

上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

Promise.any返回 p1,p2,p3 状态最先变成的 fulfilled 实例的 value,如果 p1,p2,p3 最终状态都是 reject, 则返回 All promises were rejected。

Promise.allSettled无论结果为fulfilled还是rejected,返回所有 Promise(p1,p2,p3) 实例的新 Promise,格式如下:

[
  {status: "fulfilled", value: 1},
  {status: "rejected", reason: "error"},
  {status: "rejected", reason: 2},
]

promise解决了什么问题?

promise解决了多层嵌套回调的问题。
上一个函数请求的输出作为下一个请求的输入,如果网络延迟,下一个请求执行时,很可能上一个请求还没返回值,这样就会导致请求失败。
而用promise.then()方法链式调用可以解决这个问题,当上一个then方法执行完成且成功才会调用下一个then。
缺点:
1.异步加载,延时问题
2.promise一旦创建,就会立即执行,无法取消
(可以手动取消)
//只打印ok1

Promise.resolve().then(() => {
    console.log('ok1')
    return new Promise(()=>{})  // 这样即可,返回“pending”状态的Promise对象
}).then(() => {
    // 后续的函数不会被调用
    console.log('ok2')
}).catch(err => {
    console.log('err->', err)
})

3.then方法每次调用都会创建一个新的promise对象,造成了内存的浪费

var、let和const的区别?

1、给全局添加属性:浏览器的全局对象是window,Node的全局对象是global。var声明的变量为全局变量,并且会将该变量添加为window的属性,但是let和const不会
2、变量提升:var存在变量提升现象(打印undefined),而let和const不存在,会报错(referenceError)。
3、重复声明:var变量可以重复声明,let和const不能重复声明。
4、初始值设置:在变量声明时,var 和 let 可以不用设置初始值。而const声明变量必须设置初始值
5、let声明变量可以改,const声明常量不可改,不能被再次赋值,声明变量可以改,只要保证变量的内存地址不改动,比如向数组push数据、改变对象的属性值,这些都是没问题的。

//let存在暂时性死区
let a = 'outside';
if(true) {
   console.log(a);//Uncaught ReferenceError: a is not defined
    let a = "inside";
}

typeof、instanceof、constructor的区别?

1、typeof 判断运算数的数据类型,返回字符串

typeof a=='number'/'string'/'function'/'object'/'undefined'/'boolean';
typeof null=='object';  // true
typeof []=='object';  // true
typeof []=='array';  // false
typeof b=='undefined';  // true

2、instanceof 用来判断一个变量是否是某个对象的实例,只能用来判断对象、数组和构造函数。(instanceof只能正确判断引用数据类型,而不能判断基本数据类型)

[] instanceof Array    //true
[] instanceof Object    //true

3、constructor是每一个对象都拥有的属性,而这个属性也相当于是一个指针,它指向于创建当前对象的对象。

[1,2,3].constructor==Array;    //true
[1,2,3].constructor==Object;    //false

call、apply和bind的区别

他们都是函数的方法,改变this的指向
fn.call(obj,1,2);           //立即执行,使得this指向obj
fn.apply(obj,[1,2]);      //apply需要用数组方式传递,立即执行
var f=fn.bind(obj,1,2);  //  this 会永久的指向 bind 传入的第一个参数
f();        //等调用后再执行

js获取url的参数值

function getRequest(){
    var url=location.search;   
    var theRequest=new Object();
    if(url.indexOf('?')!=-1){
        var  a=url.substr(1);
        var b=a.split('&');
        for(var i=0; i<b.length; i++){
			  theRequest[b[i].split('=')[0]]=b[i].split('=')[1]
		 }
    }   
    console.log(theRequest);   
}

addEventListenter第三个参数是什么以及它的作用?

第三个参数是boolean值,true表示事件捕获,false表示事件冒泡,默认是false。
事件冒泡:事件由子元素传递到父元素的过程叫做冒泡;
事件捕获:事件由父元素传递到子元素的过程叫做事件捕获;

纯css画三角形

width: 0;
height: 0;
border-width: 100px;
border-style: solid;
border-color: red transparent transparent transparent;

浅拷贝和深拷贝的区别?

基本数据类型只是简单的赋值数据,不存在深拷贝和浅拷贝的问题。
浅拷贝:对于引用数据类型,拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
比如改变对象的属性值,或数组push,都会影响另一个对象。
b复制了a的引用地址,而不是复制了a的值,所以是a和b共同指向了a堆内存的值。
在这里插入图片描述
实现方案:let obj2 = Object.assign({}, obj1);
注意Object.assign一级为深拷贝,二级为浅拷贝

let obj1 = { a: 0 , b: { c: 0}};
let obj2 = Object.assign({}, obj1);
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}

obj1.a = 1;    //一级
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 0}}
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}
obj1.b.c = 5;    //二级
console.log(JSON.stringify(obj1)); // { a: 1, b: { c: 5}}
console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 5}}

深拷贝:对引用数据类型,创建一个新的对象,并复制其内容和地址,此为深拷贝。
b不仅复制得到了a的内容,而且b在堆内存中有专门的内存地址为其存放内容。
在这里插入图片描述
实现方案:
let arr2 = JSON.parse(JSON.stringify(arr1));
JSON.stringify无法处理function、RegExp(正则)、new Date(),会得到字符串而不是原来的值

// 深拷贝
deepCopy(parent, clone) {
    let child = clone || {};
    for (let i in parent) {
      if (!parent.hasOwnProperty(i)) {
        continue;
      }
      if (typeof parent[i] === 'object') {
        child[i] = (parent[i].constructor === Array) ? [] : {};
        this.deepCopy(parent[i], child[i]);
      } else {
        child[i] = parent[i];
      }
    }
    return child;
  }
  var obj = deepCopy({a:[1,2,3],b:{x:10}},{}) ; console.log(obj);

**

重绘和重排的区别?

所有对元素视觉表现属性的修改,都会导致重绘,比如修改了背景颜色、文字颜色、透明度等。
所有会触发元素布局发生变化的修改,都会导致重排,比如窗口尺寸发生变化,添加、删除DOM元素,元素字体大小变化,修改了元素盒子大小如width、height、padding等。

get和post的区别?

GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。
get后退无刷新,post后退会重新发请求;
get请求能被浏览器自动缓存网页,post要手动缓存;
get有长度限制,不超过2048个字节,post长度无限制;
get参数通过url传递,post放在request body 中;
get向服务器索取数据,post向服务器提交数据。

什么是事件委托?

事件委托是利用事件冒泡,只指定一个事件处理程序来管理某一类型的所有事件。
优点:
减少事件注册,节省内存;
动态添加事件,即不用在新添加或删除的li上绑定或解绑click事件。

移动端click事件延迟300ms的原因以及解决办法?

当用户点击屏幕后,浏览器不能立即判断用户是单击还是双击缩放,因此会延迟300ms。
解决方案:
1、添加viewpoint meta标签(user-scalable=no禁止用户缩放解决安卓的300ms延迟问题)

<meta name='viewport' content='width=device-width,intial-scale=1,minimum-scale=1,maxmum-scale=1,user-scalable=no'>

2、fastClick (https://github.com/ftlabs/fastclick)
移动端事件触发顺序:touchstart–>touchmove–>touchend–>click。
fastClick.js的原理是:在检测到touchend事件的时候,会通过DOM自定义事件立即触发模拟一个click事件,并把浏览器在300ms之后真正的click事件阻止掉。
引入fastclick.js文件
window.addEventListener(function(){
FastClick.attach( document.body );
},false );

说出几个常见的状态码?

100:请求开始连接;
200:请求连接成功;
301:表示永久重定向,搜索引擎会把旧地址替换成新地址,输入www.baidu.com会跳转至https://www.baidu.com;旧地址会永久移除,搜索引擎在抓取新内容的同时将旧地址替换为新地址
302:表示临时重定向,例如未登录的用户会跳转至登录页面,搜索引擎会在抓取新内容的同时会保留旧地址;
301和302允许更改请求方法(get和post),对应的308(永久)和307(临时)不允许更改请求方法。
304:再次刷新网页返回304,表示客户端存在缓存;
400:表示服务器不理解请求的语法;(页面域名不存在或者请求参数错误)
401:用户身份未验证,需要先登录;
404:客户端请求失败,找不到该请求的链接;(未找到)
500:服务器端错误,比如tomcat正在启动;

移动端开发遇到过哪些坑?

1、IOS滚动不平滑的问题 -webkit-overflow-scrolling:touch;
2、fastclick可以解决在手机上点击事件的300ms延迟;
3、统一分辨率,禁止用户缩放;

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />

4、ios去掉移动端点击时的高亮效果

* {
  -webkit-tap-highlight-color: rgba(0,0,0,0);
}

5、 IOS中input键盘事件keyup、keydown、keypress支持不是很好
解决:可以用html5的oninput事件去代替keyup
6、input输入框聚焦时底部的按钮被弹起
解决:input聚焦时底部隐藏
7、开发App时,ios7以上顶部header和手机状态栏重合

window.uexOnload = function(type){
    var ios7style=uexWidgetOne.iOS7Style;
    var isFullScreen = uexWidgetOne.isFullScreen;
    if (ios7style == '1' && isFullScreen != '1') {
     $("body").addClass("uh_ios7");
    }
}

.uh_ios7 .uh,.uh_ios7{
    padding: 20px 0 0;
}

8、输入框元素无法自动获得焦点focus()并唤起软键盘

webview.KeyboardDisplayRequiresUserAction = "NO";

9、ios日期转换NAN的问题 ‘yyyy-MM-dd’.replace(/-/g, ‘/’)
10、ios和安卓样式不一样,ios下input输入框有阴影:-webkit-appearance: none

vue生命周期?

beforeCreate:el(整个页面Dom元素)和data还未初始化,都为undefined;
created:完成了data数据的初始化,el没有;
beforeMount:完成了el和data的初始化,但是el里面的{{message}}还没显示出来,虚拟Dom,先把位置占住;
mounted:el的{{message}}显示,完成Dom元素的挂载,这个阶段可以写入ajax请求;
beforeUpdate和updated:修改meaasge两者先后调用;
beforeDestroy和destroyed:实例销毁后,重新改变组件里的message,vue不再对此动作进行响应了。
开始创建—初始化数据—编译模板—挂载Dom—更新渲染—销毁,通俗点说Vue实例是从创建到销毁的过程。

angular生命周期?

ngOnChanges:当数据绑定输入属性(子组件通过@input方式接受父组件传过来的值)的值发生变化时调用;
ngOninit:在第一次ngOnChanges后调用,只调用一次;
ngDoCheck:用于检测和处理值的改变,可能会被多次调用;
ngAfterContentInit:被投影组件内容初始化之后调用;
ngAfterContentChecked:被投影组件内容的变更检测之后调用;
ngAfterViewInit:被投影组件视图及其子视图初始化之后调用;
ngAfterViewChecked:被投影组件视图及其子视图的变更检测之后调用;
ngOnDestroy:在Angular销毁指令/组件之前调用。

vue如何实现双向数据绑定的?

Vue数据双向绑定原理是通过数据劫持Object.defineProperty()结合发布者-订阅者模式的方式来实现的。
其核心有三点:observe、watcher、dep
observe:遍历 data 中的属性,使用 Object.defineProperty 的 get/set 方法对其进行数据劫持;
dep:每个属性拥有自己的消息订阅器 dep,用于存放所有订阅了该属性的观察者对象;
watcher:观察者对象,通过 dep 实现对响应属性的监听,监听到结果后,主动触发更新函数来更新页面。
在这里插入图片描述

使用Object.defineProperty()来进行数据劫持有什么缺点?

通过下标方式修改数组或者给对象新增属性,这些都不能触发组件的重新渲染,因为Object.defineProprety不能拦截到这些操作。
解决方案:
1、this.$set( target(Object | Array), key(propertyName | index), value )
2、还可用splice方法通过下标方式修改数组
在Vue3.0中已经不使用这种方式了,而是通过Proxy对对象进行代理,它能完美监听到任何方式的数据改变。

angular如何实现双向数据绑定的?

angular1:$scope绑定了n个属性,就会添加n个watcher,当有一个watcher发生变化时,angular就发触发$scope.$digest循环触发脏检查。
angular2:数据监听通过zoneJs实现,zoneJs就像是一个代理,它监听了angular所有的异步事件(用户输入、点击提交等;ajax请求;setTimeout,setInterval)并重写了所有的异步API(猴子补丁),一个异步事件发生时,脏检查会从根组件开始,自上而下对树上的所有子组件进行检查。zoneJs会通知angular有数据发生变化,需要检测更新。

EventLoop事件循环机制?

EventLoop指的是计算机系统的一种运行机制,js就是采用这种机制。
js事件分为同步任务和异步任务,同步任务顺序执行,异步任务分两种,宏任务(Macrotasks)和微任务(Microtasks)。
宏任务:script(整体代码)、setTimeout、setInterval、setImmediate、DOM 事件;
微任务:Process.nextTick、Promise.then、Promise.catch(注意不是new Promise);
script中的代码也是一个宏任务,所以先执行宏任务script。
执行顺序:宏任务script–>同步任务–>微任务–>宏任务。
(注意:当函数执行的时候,一旦遇到await就会先执行,等到其它操作完成,再接着执行函数体内await后面的语句。)
执行完一个宏任务1中的(同步任务和微任务),(注:如果里面还有子宏任务,则会放到宏任务的末尾成为宏任务3), 才会执行下一个宏任务2

async function async1() {
  await async2();
  console.log('async1 end');
}
async function async2() {
  console.log('async2 end'); 
}
async1();   
console.log('async3 end');
// async2 end
// async3 end
// async1 end

谈谈如何跨域?(高频问)

同源策略:域名、端口、协议相同,其中有一个不同就会产生跨域。
浏览器为什么不跨域:防止XSS、XSRF攻击,保护用户和网站的资源
localStorage、sessionStorage、cookie都不能读取
1、通过使用jsonp解决跨域
jsonp的原理就是利用<script标签没有跨域限制,通过<script标签src属性,发送带有callback参数的GET请求,Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的网站那获取资料,即跨域读取数据。
服务端不再返回 JSON 格式的数据,而是返回一段调用某个函数的 js 代码,这样实现了跨域。
你以为客户期望返回数据:[“name1”,“name2”]。
实际上客户端的数据显示为: test([“name1”,“name2”])。

<script>
    function test(json) {
        console.log('我被调用了');
        console.log(json);
    }
</script>
<script src="http://api.douban.com/v2/movie/top250?callback=test"></script>

如果要在jQuery中使用Ajax,则只需要在dataType属性中把json改为jsonp即可。注意:跨域请求是只能是get请求不能使用post请求

$.ajax({
    type: 'get',
    url: 'api/register.php',
    data:data,
    dataType: 'jsonp',
    jsonp: "callback",            //参数名
    jsonpCallback:"success",      //自定义函数名
    success:function(data){
        console.log(data);
    }
})

2、后台配置CORS解决跨域
服务器端文件加上header("Access-Control-Allow-Origin", "*");
3、通过iframe来解决跨域
基于iframe实现的跨域要求两个域具有 aa.xx.com,bb.xx.com这种主域相同的域。
http://a.study.cn/a.html 请求 http://b.study.cn/b.html
在a.html:

<!DOCTYPE html>
<html>
 <head>
 <meta charset="UTF-8">
 <title>Insert title here</title>
         <script type="text/javascript">
            document.domain = 'study.cn';
            function test() {
               alert(document.getElementById('a').contentWindow);
            }
        </script>
</head>
<body>
   <iframe id='a' src='http://b.study.cn/b.html' onload='test()'>
</body>
</html>

在b.html:

 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="UTF-8">
 <title>Insert title here</title> 
 <script type="text/javascript">
      document.domain = 'study.cn';
 </script>
 </head>
 <body>
    我是b.study.cn的body
 </body>
 </html>

这样在a页面就能获取b页面的内容了。

网络安全问题?(经常问)

XSS:跨站脚本攻击(Cross-site scripting)是一种网站应用程序的安全漏洞攻击,它允许恶意用户将代码注入到网页上,这类攻击通常包含了html以及用户端脚本语言。
XSS攻击分类
存储型:攻击者将恶意代码提交到目标网站的数据库中,服务器将数据库中的恶意代码取出并返回给浏览器执行,恶意代码窃取用户数据后就可以冒充用户的行为攻击网站。
反射型:攻击者构造出包含恶意代码的url,用户打开该url,服务端将恶意代码取出并在浏览器执行,恶意代码窃取用户数据后就可以冒充用户的行为攻击网站。
DOM型:攻击者构造出包含恶意代码的url,用户打开该url,浏览器直接执行恶意代码,恶意代码窃取用户数据后就可以冒充用户的行为攻击网站。
区别:
存储型是将恶意代码存储到数据库中,反射型是将恶意代码存在url,两者都是服务端的安全漏洞,而DOM型的恶意代码是有浏览器直接执行,属于前端安全漏洞。

例如一直弹窗:

while (true) {
   alert('你关不掉我')
}

网站左右两侧的广告栏:

img = document.createElement('img')
   img.onclick = function() {
   window.open('不好的网站')
} 

防御:
1、设置cookie的属性为HttpOnly,那么js脚本将无法读取cookie信息;
2、对用户输入进行编码,转义过滤掉特殊字符;
3、防止恶意嵌套iframe(src可以跨域)。

if(window.top !== window.self){ window.top.location = window.location;}  

判断一个页面是否存在两个窗口,只有一个窗口window.top == window.self为true。

XSRF:跨站请求伪造(Cross Site Request Forgery),诱导用户发起请求,完成一些违背用户意愿的请求(如恶意发帖、删帖、发邮件等)。
例如在论坛中发一贴,包含一链接:

www.csdnblog.com/bbs/delete_article.php?id=“X" 
只要有用户点击了这个链接,那么ID为X的这一篇文章就被删掉了,而且是用户完全不知情的情况。

防御:
1、referer验证
referer是http请求header中的一部分,例如在www.google.com里有一个www.baudu.com的链接,那么点击www,baidu,com,它的header信息里就有:

Referer:http://www.google.com

如果伪造请求的referer不是http://www.google.com,就拦截该请求。
2、token验证
如果攻击者伪造了转账的表单,那么网站可以在表单中加入一个随机的token来验证,银行服务器通过验证表单的值来判断post请求是否合法,不合法则拦截。
3、加验证码

什么是BFC?

BFC即块级格式化上下文,具有BFC特性的元素可以看做隔离了的独立容器,容器里面的子元素不会在布局上影响到外面的元素。
只要元素满足下面任一条件即可触发BFC特性:
a.body根元素
b.浮动元素:float除none以外的值
c.绝对定位元素(absolute、fixed)
d.display为inline-block、flex
e.overflow(hidden、auto、scroll)
使用场景:1、解决浮动元素高度坍塌 2、解决左边宽度固定,右边自适应

如何设置子元素高度是父元素宽度的一半?

.parent{width: 210px; height: 100px}
.child{width: 100%; padding-bottom: 50%} //width: 200px; height: 105px;

content-box和border-box的区别?

盒模型包括content、padding、border和margin
w3c盒模型content-box:宽度的呈现=width+padding+border
IE盒模型border-box:宽度的呈现=width(包含了padding、border)

数组去重?

var arr = [1,1,1,2,3,3,4]
1、function unique1(){
    var newArr = [];
     for(let i in arr){
        if(newArr.indexOf(arr[i]) == -1){
           newArr.push(arr[i]);
        }
     }
    console.log(newArr);
}
unique1();

2、function unique2(){
    var newArr = [];
    var newObj = {};
     for(let i in arr){
        if(newObj[arr[i]] == undefined){
           newArr.push(arr[i]);      
           newObj[arr[i]] = 1;     
        }
     }
    console.log(newArr);    //[1,2,3,4]
    console.log(newObj);   //{1:1,2:1,3:1,4:1}
}
unique2();

3、function unique3(){
    return Array.from(new Set(arr));  
    //return [...new Set(arr)]; 
    //new Set()对象存储的值是唯一的,Array.from将一个有length属性的对象或类数组转换成真正的数组
}
unique3();

找出一串字符串中重复的字符和长度?

1、var str = 'adddfxssx';
function func(){
  var obj = {};
  for(let i = 0; i<str.length; i++){
    if(!obj[str[i]]){
      obj[str[i]] = 1;
    }else{
      obj[str[i]]++;
    }
  }
  return obj;
}
func();   //{a: 1, d: 3, f: 1, x: 2, s: 2}
2、var str = 'adddfxssx';
function func(){
  var arr = [];
  var obj = {};
  for(let i = 0; i<str.length; i++){
    if(arr.indexOf(str[i]) == -1){
      arr.push(str[i]);
      obj[str[i]] = 1;
    }else{
      obj[str[i]]++;
    }
  }
  return obj;
}
func();    //{a: 1, d: 3, f: 1, x: 2, s: 2}

冒泡排序?

function bubbleSort(arr) {  
  for(let i = 0;i<arr.length-1;i++) {     //外层下标0,1,2,3
      for(let j = i+1;j<arr.length;j++) {    //内层下标1,2,3,4
        if(arr[i]>arr[j]) {
           let tem = arr[i];
           arr[i] = arr[j];
           arr[j] = tem;
        }
      }
  }
  return arr;
}
bubbleSort([2,1,4,5,3]);

字符串反转?

function reverse(str){
   for(let i = 0; i<str.length; i++){
      return str.split('').reverse().join('');
   }
}

new的四个步骤?

var obj = new Func();
1.创建一个空对象

var obj = {};

2.链接到原型(将构造函数的prototype赋值给新对象的_proto_)

obj._proto_ = Func.prototype;

3.绑定this,并执行构造函数的代码(this指向obj,不用new指向window)

Func.apply(obj,arguments);

4.返回新对象

return obj

js延迟(异步)加载的5种方式?

1.defer属性:告诉浏览器立即下载该js文件,但该脚本会延迟到整个页面解析完毕之后再执行
2.async属性:下载完毕立即执行该脚本,有可能会阻断HTML的解析
两者都不能控制加载文件先后的顺序。
即:如果依赖其他脚本和 DOM 结果,使用 defer
如果与 DOM 和其他脚本依赖不强时,使用 async

在这里插入图片描述

3.动态创建DOM(放在body标签上面,接近页面底部)

<script type="text/javascript">  
   (function(){     var scriptEle = document.createElement("script");
     scriptEle.type = "text/javasctipt";
     scriptEle.async = true;
     scriptEle.src = "http://cdn.bootcss.com/jquery/3.0.0-beta1/jquery.min.js";
     var x = document.getElementsByTagName("head")[0];
     x.insertBefore(scriptEle, x.firstChild);
 })();</script>  

4.setTimeout延迟
5.把js放底部最后加载

vue和angular的区别?

jquery和三大框架我理解的区别一个是居于DOM的操作,一个居于数据的操作。
1.vue和angular相比体积更小,同样项目占的内存大概是angular的一半。
2.vue相比angular更加灵活,可以直接像引用jquery那样在html中引用vue。
3.angular模板功能强大,指令丰富,是一个比较完善的框架,包括服务、模板、双向数据绑定、路由等,复杂度高一点。而vue要配合vuex(状态管理)和vue-router这两个单独的插件来使用。
4、两者双向数据绑定的原理不一样

rem的本质?

rem布局的本质是等比缩放,作用于非根元素时,它是相对于根元素。作用于根元素时,相对于浏览器原始字体大小。
em是字体大小是相对于父元素。

javascript垃圾回收机制?

执行环境负责管理代码执行过程中使用的内存,垃圾收集器会定时找出那些不再继续使用的变量,回收释放内存。
1、标记清除法(标记为0的清除掉,标记为1的不清除,缺点是释放的内存空间不连续,当分配空间需要遍历找到大于size的块才能为其分配)
2、引用计数法(标记为0的清除掉,数字递增的不清除,缺点是计数器无上限,计数器也很占空间)
例如:
清理定时器clearTimeout;
把变量设置成null;
合理使用全局变量;

HTML语义化?

1.代码结构,为了在没有css的情况下,页面也能很好的呈现内容结构和代码结构。
2.语义化,h表示标题,p表示段落,title和alt解释名称和图片信息(title是鼠标滑过出现的备注信息,而alt是图片未加载出现的备注信息)
3.有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息

png、jpg、svg的区别?

1.png、jpg是位图,由屏幕上的像素构成,svg是矢量图,由一系列计算机指令来描述和记录一幅画。
2.png可以无损压缩,jpg压缩多次图片质量变差,svg体积更小,任意放大也不会损失图片质量。
base64文本文件,适合小图标,通过对Base64编码将结果写入到HTML或CSS,从而减少HTTP文件。

pc端和移动端区别?

1、pc端考虑的是浏览器兼容性,而移动端开发考虑的是手机兼容性。
2、移动端有触屏事件,而缺少hover事件,另外移动端有弹出手机键盘的处理,而pc端没有。
3、在动画支持上,移动端使用css3的兼容性更好。
4、手机上有300ms的延迟,pc端没有
5、pc端更新不需要重新下载,APP要重新下载。

h5开发和混合APP开发的区别?

h5
1、支持设备广,可跨平台,一套代码可以在ios、android、pc端上通用。
2、不能访问设备的一些硬件条件(摄像头、麦克风等)。
APP:
1、一套代码可以在ios、android上通用。
2、如果要上线的话要发到appStore或应用市场审批。
3、获得新版本的话要重新下载更新。

return和return true、return false的区别?

return是终止程序不再继续往下执行。
return true是返回正常的处理结果,后面的语句不再执行。
return false是终止事件的默认行为,比如事件冒泡、阻止表单提交,a跳转。
return+表达式 结束函数执行,表达式的值作为函数的结果。

强制转换和隐式转换?

String(),Number(),parseInt()函数是强制转换
不同类型的变量比较要先转类型,叫做类型转换,类型转换也叫隐式转换。隐式转换通常发生在运算符加减乘除,等于,还有小于,大于等。

判断一个对象是不是空对象?

1、Object.keys(obj).length === 0;
2、JSON.stringify({}) == '{}'

link 标签 和 import 标签的区别?

link 属于 html 标签,而@import 是 css 提供的;
页面被加载时,link 会同时被加载,而@import 引用的CSS会等到页面加载完再加载;
link 是 html 标签,因此没有兼容性,而@import 只有 IE5 以上才能识别;
link 方式样式的权重高于@import 的。

块元素和行元素?

块元素:独占一行,并且有自动填满父元素,可以设置 margin 和 padding 以及高度和宽度
行元素:不会独占一行,width 和 height 会失效,并且在垂直方向的 padding 和 margin 会失效。
行块元素:img、input

==、===的区别?

===:称为等同符,值和类型都相同才返回true;
==:称为等值符,当等号两边的类型相同时,直接比较值是否相等,若不相同,则先转化为类型相同的值,再进行比较;

setTimeout中var和let的区别?

for(var i=0;i<5;i++) { 
  setTimeout(function(){ 
    console.log(i);   //5,5,5,5,5
  },1000); 
}
就是每个i都是指向同一个,i=5,然后打印5个5
for(let i=0;i<5;i++) { 
  setTimeout(function(){ 
    console.log(i);   //0,1,2,3,4
  },1000); 
}
每次循环都会生成不同的i,i为0,1,2,3,4

JSON和JSONP?

json返回的是一串数据对象;而jsonp返回的是脚本代码

Ajax是什么?

Ajax = 异步JavaScript和XML
发出HTTP请求时,实现了页面在不刷新浏览器的情况下与服务器进行交互。例如鼠标滑过菜单出现详细列表。点击加载更多数据等。

null和undefined和NaN?

null表示一个无的空对象,undefined表示一个无的原始值
NaN(not a number),表示非数字。
typeof null //Object
typeof undefined //undefined
typeof NaN // 返回number,神奇

$(this)和this关键字在jquery中的不同?

$(this)返回一个Jquery对象,可以调用Jquery方法,比如hide()、show()方法。
this代表当前DOM元素。

JavaScript的栈和堆?

1、堆是动态分配内存,内存大小不一,也不会自动释放。栈是自动分配相对固定大小的内存空间,并由系统自动释放。
2、基本数据类型是按name、value直接存放在栈中的,而引用数据类型的value存放的是数据的指针,当访问引用数据类型的值时,先从栈中获得对象的指针,通过指针找到堆中所需要的数据,引用数据类型如下图。
在这里插入图片描述

同步任务和异步任务?

因为Javascript的单线程,所有任务都要排队,前一个任务执行完,才能继续执行下一个任务,当遇到ajax请求获取大量数据时,用户只能干等着,严重影响用户体验。因此就有了同步任务和异步任务。
同步任务:主线程上排队执行任务,只有前一个任务完成,才能继续执行下一个任务。
异步任务:是指不进去主线程,先挂起进入到任务队列,js的宿主环境(浏览器、node)是多线程的,使得js拥有了异步的属性。
比如一个ajax请求,它不会像我们想象的直接拖到同步任务之后,当主线程遇到异步请求时,浏览器会开一条新的http线程来执行请求,当这个异步请求执行完毕时,任务队列就会把完成的事件插入到主线程的尾部等待输出。

…args(剩余参数)和arguments的区别?

在这里插入图片描述
剩余参数表示那些没有对应形参的实参,arguments包含了传给函数的所有实参,有length属性。
可以通过[...arguments]Array.prototype.slice.call(arguments)转化为真正的数组。

TypeScript和JavaScript的区别?

TypeScript是JavaScript 的一个超集(js里有的东西ts都有),支持 ECMAScript6标准。与js最大的区别就是ts添加了可选的静态类型(简单理解为使用变量先先声明数据类型)和基于类(类、接口、继承等)的面向对象编程思想。
还有IDE增强功能,提供代码补全、错误提示、跳转定义、重构等等。

TCP和UDP区别?

tcp(Transmission Control Protocol),传输控制协议,传输数据前需要先建立连接,是一种可靠的、基于字节流的传输层通信协议;
udp(User Datagram Protocol),用户数据报协议,传输数据的时候不需要建立连接,是一种传输报文的简单不可靠的信息传送协议。

高内聚低耦合?

高内聚:设计的时候将相关的功能内聚到一块,比如下单模块包括产品信息,用户信息、订单信息。
低耦合:描述了模块与模块之间的依赖,当更改其中一个模块,另一个模块的影响越小,耦合性就越低。

v-if和v-show的区别?

v-if是dom元素的销毁和重建,可以用在判断不同角色拥有不同功能,或者id=1,2,3展示不同;
v-show表示存在这个dom元素,它是通过元素的display来实现显示和隐藏,频繁切换用v-show,可以用在tab切换。
v-if有更高的切换开销,v-show有更高的初始渲染开销

脏检查是什么意思?

脏检查的全名是 脏数据检查。是AngularJS命名的。
脏数据也就是产生了变化的数据。
脏检查为什么被称为脏。它是周期检查而不是直接监听属性变化。我们把这个检查称为摘要周期(digest)。
angularJS监测对象变化不是像vue.js那样通过Object.defineproperty这种接口,而是在某些情况下制定策略,通过复制保存一份数据,进行快照对比,来监测变化。

什么是双向数据绑定?

双向数据绑定是UI视图(view)和数据(model)相互绑定在一起,当数据发生改变时,UI视图也发生改变,反之UI视图改变数据同步发生改变。
双向数据绑定最开始出现在表单中,在表单输入数据的时候就改变对象的属性值,反之对应属性值改变也会反映到表单中。
目前流行的 MVVM 框架(Angular、Vue)都实现了双向数据绑定,这样也就实现了视图层和数据层的分离。

no-cache 和 no-store 的区别

no-cache:表示可以在客户端存储资源,每次发请求给服务端来获取资源(200)还是使用客户端缓存(304)。
no-store:不在客户端存取资源,每次发请求给服务器重新拉取资源。

两边宽固定,中间自适应(flex布局)?

父元素display: flex; 左右flex: 0 0 200px; 中间flex: 1 1 auto;

async函数的优点?

到 Promise 对象,再到 Generator 函数,把异步写法的复杂性变成了形式上同步的写法,但是这种改进还是不彻底,于是就有了async\await。async 函数,就是 Generator 函数的语法糖。
async是把Generator函数的*号换成async,yield换成await。
1、内置执行器
Generator函数的执行必须靠执行器(.next()),而async函数自带执行器,和普通函数一样,直接调用。
2、语义化更好
async和await,比起星号和await,语义更清楚,async是声明函数是异步的,而await是用于等待一个方法执行完成。await会阻塞后面的代码(先执行第一个await,再执行async函数外的同步函数代码,然后再执行第二个await),如果等到的是 Promise 对象,则得到其 resolve 值。否则,会得到一个表达式的运算结果。
3、更广的实用性
yield 命令后面只能是 Thunk 函数或 Promise 对象,async 函数的 await 命令后面,可以跟 Promise 对象和普通表达式。
缺点:
await 会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性。

箭头函数和普通函数的区别?

1、箭头函数省略了function和return。
2、箭头函数没有arguments对象和prototype对象,不能用new实例化。
3、箭头函数中this的指向和普通函数不一样,全局作用域下声明的箭头函数this指向window,函数中包裹箭头函数,它的this和最外层非箭头函数的this指向一致。并且apply、call不能改变this的指向。

nginx反向代理与负载均衡的实现?

用户访问网站的时候首先会访问nginx服务器,然后nginx服务器再从公司的服务器集群中选择压力较小的服务器,将该访问引向该服务器,但是用户并不知道是哪一台服务器提供的数据,这就是反向代理。

vue中为什么data是一个函数?

组件中的data写成一个函数,数据以函数返回值的形式定义,这样每复用一次组件,就会返回一份新的data,类似给每个组件实例创建一个私有的数据空间,如果写成对象模式的话,所有组件实例就公用了一份data,改变一个data其它的也会改变。

对vuex的理解?

vuex是专门为vue提供的全局状态管理系统,用于多个组件中数据共享、数据缓存等。
主要包括以下模块对象:
State: 定义了应用状态的数据结构,可以在这里设置默认的初始状态,类似data。

Getter: 类似于计算属性computed,允许组件从Store中获取数据(this.$store.getters.doneTodosCount)。

Mutation: 是唯一更改store中状态的方法,且必须是同步函数(this.$store.commit(‘mutation的方法’,arg))。

Action: 用于提交mutation,而不是直接变更状态,可以写入异步操作(this.$store.dispatch(‘action的方法’,arg))。

Module: Vuex允许我们将store分隔成模块,每个模块拥有自己的state、getter、mutation、action、Module允许将多个store保存在同一个状态树中。

mixins和vuex的区别?

vuex公共状态管理,如果其中一个组件改变了vuex的数据。那么其它引入vuex的组件数据也会相应改变,类似于浅拷贝。
mixins如果被多个组件引入,在每个组件中是独立的,互不影响,改变其中一个组件的数据不会影响到其它,类似于深拷贝。

什么是虚拟DOM?

如果要频繁的操作DOM,那就借助虚拟DOM尽可能的一次性将差异更新到真实DOM中,这样保证了DOM不会出现性能很差的问题。Virtual DOM的diff就是比较新旧虚拟DOM Tree找出差异并更新。
diff的过程:
1、用JS对象模拟DOM(虚拟DOM ,vue生命周期beforeMount)
2、把此虚拟DOM转成真实DOM并插入页面中(createElement方法,vue生命周期mounted)
3、如果有事件发生修改了虚拟DOM,比较两棵虚拟DOM树的差异,得到差异对象(diff算法)
4、把差异对象应用到真正的DOM树上(patch方法)
虚拟DOM的缺点:
1、首次渲染真实DOM时,还要多渲染一层虚拟DOM,会比较慢。
2、如果修改非常少量的虚拟DOM,实际上有可能比操作真实DOM更慢。

vue模板template编译成render函数的原理?

1、使用正则对template字符串进行解析转化为抽象语法树AST
2、遍历AST,找到静态节点并跳过,优化runtime的性能
3、AST转化为render函数

单向数据流?

数据流和数据绑定是两个概念,单向数据流,即父组件可以向子组件传递props,但是子组件不能修改父组件传递来的props,子组件只能通过事件通知父组件进行数据更改。

computed和watch的区别?

computed计算属性:依赖data或者父组件传递过来的props中的数据,并且computed的值有缓存,只有它依赖的属性值发生改变,下一次获取computed的值时才会重新计算。
watch侦听器:更多的是观察的作用,无缓存性,类似于某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作(当值第一次绑定的时候不会执行监听函数(除非设置immediate:true),只有值发生改变才会执行)。

localstorage是否可以替代vuex?

对于不变的数据确实可以,但是当两个组件共用一个数据源时,如果其中一个组件改变了该数据源,希望另一个组件响应该变化时,localstorage,sessionstorage无法做到。

B端和C端的区别?

B端产品大多面对企业用户,本质时满足工作需要,且业务场景多,流程多。
C端产品大多针对某一主要群体,始终都是围绕产品核心功能展开的,逻辑相对简单,主要解决一个核心痛点,整个产品的设计都始终围绕这一核心功能及主线流程展开。

hash模式和history模式的区别?

hash模式路由路径用#拼接,当#后面的路径发生变化时,会触发hashchange事件window.addEventListener(‘hashchange’, fn),并且在浏览器的访问历史中增加一个记录;
history API是H5提供的新特性,之前有back,forward,go方法,之后在HTML5中新增了pushState()和replaceState()方法,如果改变页面地址,强制刷新浏览器时,如果服务器没有该页面的接口会出现404错误;
1.hash通过监听浏览器的onhashchange()事件变化,查找对应的路由规则
2.history原理: 利用H5的 history中新增的两个API pushState() 和 replaceState() 监听URL变化

vue模版编译原理?

1、将template字符串转为AST抽象语法树(语法树就是树形的对象)
2、优化AST语法树,主要标记一些节点内容不变的静态节点(patch更新对比时会跳过这些节点的对比和重新渲染)
3、将优化好的AST语法树,通过递归的方式,拼接为render方法的字符串,最后执行new Function,转为render方法(render是使用js的完全编程能力来渲染页面,即用js来构建DOM)。
4、render函数生成对应的虚拟dom,最后生成真实dom

画一条0.5px的线?

1、transform: scale(0.5,0.5)
2、<meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5"/>

interface和class、type的区别?

1、interface和type都可以用来声明对象和函数类型,type还可以声明基本类型、联合类型,interface不行
2、interface可以声明合并,type不可以
3、interface用extends来扩展,而type用&操作符扩展

interface: 接口只声明成员方法,不做实现。
class: 类声明并实现方法。

interpace Person{
    name: string,
    age: number,
    printName(): void
}
class Person{
   name: string,
    age: number,
    printName(): function(){
         console.log(this.name)
   }
}
const person1: Person{
    name: 'xjy',
    age: '18',
    printName(): function(){
         console.log(this.name)
   }
}

extends 和 implements区别?

extends 可以理解为 es6 class 对应的 extends,除了继承父类的方法和属性,还可以自定义自己的属性和方法
implements 理解为实现,A implements B,A 上要有 B 对应的属性和方法
在这里插入图片描述

extends只能继承一个,implements可以实现多个

TS中的泛型?

泛型是指在定义函数、接口或类的时候,不预先指定具体类型,而是在使用的时候再指定类型
泛型中的T就像一个占位符、或者说一个变量,在使用的时候把定义的类型像参数一样传入,它可以原封不动的输出

vue父子组件的生命周期?

创建阶段:
父组件beforeCreate–父组件created–父组件beforeMount–子组件beforeCreate–子组件created–子组件beforeMount–子组件mounted–父组件mounted
运行阶段:
父组件 beforeUpdate–>子组件beforeUpdate–>子组件updated–>父组件updated
销毁阶段:
父组件 beforeDestroy–>子组件beforeDestroy–>子组件destroyed–>父组件destroyed

vue路由中query和params的区别?

1、query在刷新页面的时候参数不会消失,而params在刷新页面的时候会消失
2、query传过来的参数会显示在地址栏上,类似?id=1,params类似post,不会在url上拼接参数

vue的优缺点?

优点:
1、虚拟DOM,性能更快;
2、双向数据绑定;
缺点:
1、不利于SEO,vue里面的大部分数据是存在于js代码里面的,而搜索引擎请求到的html是没有渲染数据的;
2、SPA单页面白屏,首次请求会在首页的时候将所有的js、css数据全部加载,当项目过于庞大时,这个白屏时间就会比较明显;
3、不支持IE8及以下的浏览器,vue的底层原理使用了Object.defineProperty,并且Vue需要Promise的支持,IE8同样不支持Promsie;
4、简单页面不适用虚拟DOM;

vue的优化:
1、路由懒加载、组件懒加载
2、第三方库(例如elementUI)按需引入
3、keep-alive缓存组件
4、v-for 遍历避免同时使用 v-if
5、webpack的优化

为什么v-for和v-if不能同时使用?

因为v-for的执行会比v-if要高,循环10次就要进行10次的判断,比较消耗性能
解决:1、外层嵌套空标签template(页面渲染不生成dom)上加入v-if
2、计算属性computed提前filter过滤掉那些不需要显示的项

使用v-for时不能用index作为key?

1、影响性能
2、如果数组有四个元素,用key = index绑定元素,当删除数组中的第二个元素且第二个元素刚好被选中时,会显示第三个元素被选中,导致bug

dns查询过程(递归加迭代):

www.baidu.com为例:
本地DNS服务器—根DNS服务器.(得到顶级域(TLD)DNS服务器的IP)
本地DNS服务器—顶级域DNS服务器com(得到权威DNS服务器的IP)
本地DNS服务器—权威DNS服务器baidu.com(得到url地址对应的IP)
在这里插入图片描述

vue中怎么检测数组变化?

数组就是使用object.defineProperty重新定义数组的每一项,那能引起数组变化的方法有pop、push、shift、unshift、splice、sort、reverse这七种
主要是用函数劫持的方式,重写了数组方法,具体就是更改了数组的原型,更改成自己的,用户调数组的一些方法的时候,走的就是自己的方法来更新视图

computed的实现原理?

computed本质是一个惰性求值的观察者。其内部实现了一个惰性的watcher,它不会立即求值,computed会通过watcher.dirty控制是否读取缓存。

小程序的双线程模型?

微信客户端是小程序的宿主环境,宿主环境为了执行小程序的各种文件(wxml文件、wxss文件、js文件)提供了小程序的双线程模型:渲染层和逻辑层
wxml模块和wxss样式运行于渲染层,渲染层使用webview线程渲染(一个程序有多个页面,会使用多个webview的线程)。JS脚本(app.js/home.js)属于逻辑层,逻辑层使用JsCore(专门处理JS脚本的引擎)运行JS脚本。

可选链?.和??的区别?

在不确定某个值是否为undefined或者null时,可以选用?.可选链
当左侧的操作数为undefined或者null时,返回其右侧操作数,否则返回左侧操作数

let person = {
   age: 18,
   name: 'xjy'
}
let p1 = person?.sex ?? '女'
console.log(p1);  // 女
let p2 = person?.age ?? '20'
console.log(p2);  //18

vue2和vue3的区别?

1、Vue 3 的 Template 支持多个根标签,Vue 2 不支持
2、创建实例:
vue2:引入vue构造函数,使用new Vue()来创建实例
vue3:按需引入,直接用引入的createApp来创建实例
3、API的风格
vue2 options API需要在data、computed、created、method中不断的编写、修改,代码量大的话修改起来比较痛苦
vue3 composition API能将相关的代码、函数有序的组织在一起,都写在setup函数里面,使代码看上去更加的简洁,方便封装复用
4、响应式原理
vue2采用的是object.defineProperty()结合发布订阅的模式来实现双向数据绑定
vue3采用的Proxy来拦截对象属性的任意变化,Object.defineProperty监听对象属性。而Proxy监听的是整个对象

diff算法?

diff算法将虚拟DOM的某个节点数据改变后生成新的节点与旧节点进行比较,并替换为新的节点,具体就是调用patch方法,比较新旧节点,一边比较一边给真实DOM打补丁进行替换。
diff算法有以下过程:
vue2的核心算法采用了双端比较的算法,同时从新旧节点的两端开始比较,借助key值找到可复用的节点
同级比较,再递归比较子节点
如果节点类型不同,直接移除旧节点,再创建并插入新节点,不会在比较这个节点以后的子节点

插槽的用法?

第一种:
在这里插入图片描述
在这里插入图片描述
第二种:
在这里插入图片描述
在这里插入图片描述

强类型语言和弱类型语言?

强类型语言:
所有变量都必须先定义后使用,并且使用时不能再改变数据类型
弱类型语言:
简单理解就是一种变量类型可以被忽略的语言,比如自动转换数据类型‘12’+3=123

强类型语言带来的严谨性可以统一代码规范、提高代码质量,有效地帮助避免许多错误。

小程序和内嵌h5两者之间的通信?

微信小程序
.wxml

<view>
  <web-view src="{{webUrl}}"  bindmessage="msgHandler"></web-view>
</view>

.js

Page({
	// 小程序端
	// 传递值
	data: {
	  webUrl: "http://www.baidu.com?id=10"  //内嵌的h5并传入参数,h5在created()直接接受参数
	},
	 // 小程序端
	 // 接收值
	 msgHandler: function (e) {    //(h5像小程序传递参数)
	   console.log(e) //小程序接收参数
	 }
 })

h5页面

在h5中要先引入jssdk
// h5端
// 传递值
wx.miniProgram.navigateTo({url: '/organization/organization'}). //跳转到小程序
wx.miniProgram.postMessage({ data: '参数' }) // 并传参

// h5端
// 接收值 接收小程序传过来的值
function getParams(name) {
  var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
  var r = window.location.search.substr(1).match(reg);
  if (r != null) {
    return r[2];    // 如果小程序那边值加密了,这边就需要进行解密 decodeURIComponent(r[2])
  }
  return null;
}

let token = getParams('id');

前端数据加密的几种方式?

base64加密:就是包括小写字母a-z、大写字母A-Z、数字0-9、符号"+“、”/"一共64个字符的字符集
MD5 加密方式:MD5.JS库是通过前台js加密的方式对密码等私密信息进行加密的工具。
encodeUrl和decodeUrl编码解码:有局限性

vue2在组件中封装使用v-model?

父组件:

<show-model v-model="inputvalue"></show-model>

子组件:

<template>
  <div>
    <div>内容: <input type="text" :value="value" @input="inputHandle" /></div>
    <div>{{ value }}</div>
  </div>
</template>

<script>
export default {
  props: ["value"],
  name: "vmodel",
  methods: {
    inputHandle(e) {
      this.$emit("input", e.target.value)
    },
  },
}
</script>

nextTick的作用和原理?

作用:vue中的nextTick主要用于处理数据动态变化后,DOM还未及时更新的问题,用nextTick就可以获取数据更新后最新DOM的变化。

原理:vue在观察到数据变化时并不是直接更新DOM,而是开启一个队列,并缓冲在同一个事件循环中,在缓冲时去除重复数据,从而避免不必要的计算和DOM操作,在下一个事件循环tick中,Vue刷新队列并且只执行最后一次改变,所以它能获取到最新DOM的变化。

http1.0和http2.0的区别?

https://blog.csdn.net/qq_37012533/article/details/84620865

原型和继承

https://blog.csdn.net/qq_37012533/article/details/84984570

浏览器的兼容性问题?

https://blog.csdn.net/qq_37012533/article/details/84786135

简单总结position定位和元素水平垂直居中(经常问)

https://blog.csdn.net/qq_37012533/article/details/84958566

MVC、MVVM的区别和联系?

https://blog.csdn.net/qq_37012533/article/details/84951655

谈谈网站性能优化?(重点问)

https://blog.csdn.net/qq_37012533/article/details/84632930

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值