面试总结

一、JS

1. js的数据类型,简单类型和引用类型

8种:nullundefinedNumberStringBooleanobjectsymbolbigInt指安全存储、操作大整数

 

基础类型包括:number,string,null,undefined,Boolean,symbol。

基础类型存储的空间很小,存放在栈(stack)中方便查找,且不易于改变。(传值)

引用类型包括:Object

引用数据类型(存放在堆内存中的对象,每个空间大小不一样,要根据情况进行特定的配置)(传址)

 

Symbol:防止对象的属性名相同。在ES5种属性名都为字符串。 Symbol不是对象,不能使用new、每一个symbol都不一样,可有效防止属性名相同。Symbol作为属性名时只能使用[]进行访问。属性名的遍历有自己的方式object.getOwnPropertySymbols。

 

bigInt指安全存储、操作大整数

 

2. typeof函数

typeof 运算符返回一个用来表示表达式的数据类型的字符串。
可能的字符串有:"number"、"string"、"boolean"、"object"、"function" 和 "undefined"。

表达式

返回值

typeof undefined

'undefined'

typeof null

'object'

typeof true

'boolean'

typeof 123

'number'

typeof "abc"

'string'

typeof function() {}

'function'

typeof {}

'object'

typeof []

'object'

不能判断引用类型:数组、对象

判断为数组的方式:1.instanceof 2.constructor 3.Object.prototype.toString.call(a) === '[object Array]';//true  

4、Array.isArray()

 

 

 

3. 堆、栈、队列,浏览器执行任务的过程。

栈:基本类型采用,存储空间很小。

堆:引用类型采用,存储空间不一定。

队列:分为前端和后端,在前端进行删除,在后端进行插入。

1) 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

2) 主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

3) 一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

4) 主线程不断重复上面的第三步。

 

执行完同步任务之后,查看执行栈是否为空,如果为空,则执行宏任务,每次宏任务执行完成之后,都去看微任务。微任务有则执行微任务,没有执行宏任务,宏任务,微任务一直循环往复。

 

宏任务DOM事件回调函数、异步http请求、setTimeout、setInterval、setImmediate(node)JavaScript全部代码

微任务process.nextTick、Promise、Mutation Observer

4. 深拷贝和浅拷贝

浅拷贝:会影响原来的值,主要针对基础类型

方法:

1.扩展运算符

2.Array.prototype.slice

3.object.assign({},object)

4.concat()、slice()-----只适合一维数组

   深拷贝:不影响原来的值,主要针对引用类型

   方法:

  1. JSON.stringfy和JSON.parse()

缺点

① 如果obj里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式,而不是对象的形式。

② 如果obj里有RegExp(正则表达式的缩写)、Error对象,则序列化的结果将只得到空对象;

③ 如果obj里有函数,undefined,则序列化的结果会把函数或 undefined丢失;

④ 如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null

JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;

⑤ 如果对象中存在循环引用的情况也无法正确实现深拷贝;

  1. $.extend([deep],target,object1,...)
  2. For in +递归
  3. Loadsh中的clonedeep

5. callapplybind

call(this,arg1,arg2,arg3)

apply(this,[arg1,arg2])

bind(this,arg1,arg2)

bind不会立即调用,而是返回一个新函数,其中的this指向是创建bind的第一个参数,其他则会使用为参数。

6.New创建实例

  1. 创建一个新的空对象
  2. 将新对象的 __proto__ 指向构造函数的prototype
  3. 将构造函数中this指向新对象(借助 call/apply)
  4. 判断构造函数的返回值

1设置了返回值:
若返回值为引用值,则返回引用值
若返回值为原始数据,则返回新对象

2未设置返回值:返回新对象

7.html5中的webGL

canvas创建画布,获取上下文getContext(‘2d’),设置宽高,绘画。

 

webGL:投影矩阵的坐标和投影矩阵的颜色,CPU显卡之间,确定位置生成相对应的像素。

 

jTopo(Javascript Topology library)是一款完全基于HTML5 Canvas的关系、拓扑图形化界面开发工具包。

8. forEachmap的区别

1map速度比foreach

2map会返回一个新数组,不对原数组产生影响,foreach不会产生新数组,foreach返回undefined

3map因为返回数组所以可以链式操作,foreach不能

4, map里可以用return ,foreach里用return不起作用,foreach不能用break,会直接报错

forEach调用的函数抛出异常,循环终止。

Map会返回一个新数组,可以链式操作。forEach不会产生新的数组,遍历谁就返回谁。

9. axiosfetchajax的区别

Fetch的使用:fetch是基于promise,可链式调用,返回promise

 

fetch(url).then(response => response.json())

  .then(data => console.log(data))

  .catch(e => console.log("Oops, error", e))

 

fetch

1.Fetch是基于promise实现的,也可以结合async/await

2.fetch请求默认是不带cookie的,需要设置fetchURL{credentials:include})
3.Credentials有三种参数:same-origininclude*

4.服务器返回400 500 状态码时并不会reject,只有网络出错导致请求不能完成时,fetch才会被reject

5.所有版本的 IE 均不支持原生 Fetch

fetchwidow的一个方法;

5.fetch api 可以跨域。也可以通过CORS进行设置,进行跨域传输。

6.fetch不支持超时timeout处理.解决方法:1.setTimeout 2.Promise.race()

7.fetch不支持jsonp

8.fetch不支持progress事件

 

针对Fetch的兼容性问题:采用fetch polyfill

Fetch默认不带cookie,则在需要验证的信息的时候。可以设置credentials

omit: 默认值,忽略cookie的发送

same-origin: 表示cookie只能同域发送,不能跨域发送

include: cookie既可以同域发送,也可以跨域发送

 

ajax

XMLHTTPRequest的一个实例;

只有当状态为200或者304时才会请求成功;

 

Axios

特点:1.同时支持浏览器端和服务端的请求。(根据XMLHttpRequestprocess两个变量来判断是哪个环境)

2.支持promise

3.支持数据请求和返回的拦截

4.转换请求返回数据,能自动转换为JSON

5.可取消请求

6.客户端防止XSRF(跨站请求伪造) (判断请求tooken是否相同)

7.Node端支持代理

8.在内部对一些请求格式做了一些封装。

 

 

10. 为啥跨域中出现options请求

转自或参考:跨域中option请求详解
https://www.cnblogs.com/zhaodagang8/p/11275685.html

在正式跨域的请求前,浏览器会根据需要,发起一个“PreFlight”(也就是Option请求),用来让服务端返回允许的方法(如getpost),被跨域访问的Origin(来源,或者域),还有是否需要Credentials(认证信息)

 

三种场景:

1. 如果跨域的请求是Simple Request(简单请求 ),则不会触发“PreFlight”Mozilla对于简单请求的要求是:

以下三项必须都成立:

1. 只能是GetHeadPost方法

2. 除了浏览器自己在Http头上加的信息(如ConnectionUser-Agent),开发者只能加这几个:AcceptAccept-LanguageContent-Type、。。。。

3. Content-Type只能取这几个值:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain

一、为什么会出现options请求呢?

 跨域请求中,options请求是浏览器自发起的preflight request(预检请求),以检测实际请求是否可以被浏览器接受。

preflight request请求报文中有两个需要关注的首部字段:

1Access-Control-Request-Method:告知服务器实际请求所使用的HTTP方法;

2Access-Control-Request-Headers:告知服务器实际请求所携带的自定义首部字段。

同时服务器也会添加origin header,告知服务器实际请求的客户端的地址。服务器基于从预检请求获得的信息来判断,是否接受接下来的实际请求。

服务器所返回的Access-Control-Allow-Methods首部字段将所有允许的请求方法告知客户端,返回将所有Access-Control-Request-Headers首部字段将所有允许的自定义首部字段告知客户端。此外,服务器端可返回Access-Control-Max-Age首部字段,允许浏览器在指定时间内,无需再发送预检请求,直接用本次结果即可。

在我们开发过程中出现的浏览器自发起的options请求就是上面的第二种情况。实际上,跨域请求中的复杂请求发出前会进行一次方法是optionspreflight request

二、当跨域请求是简单请求时不会进行preflight request,只有复杂请求才会进行preflight request

跨域请求分两种:简单请求、复杂请求;

符合以下任一情况的就是复杂请求:

1.使用方法put或者delete;

2.发送json格式的数据(content-type: application/json

3.请求中带有自定义头部;

除了满足以上条件的复杂请求其他的就是简单请求喽!

三、为什么跨域的复杂请求需要preflight request

复杂请求可能对服务器数据产生副作用。例如delete或者put,都会对服务器数据进行修改,所以在请求之前都要先询问服务器,当前网页所在域名是否在服务器的许可名单中,服务器允许后,浏览器才会发出正式的请求,否则不发送正式请求。

http请求中为啥会出现options?

1、跨域请求,非跨域请求不会出现options请求
2、自定义请求头
3、请求头中的content-typeapplication/x-www-form-urlencodedmultipart/form-datatext/plain之外的格式

解决方法:直接使用ajax跨域访问、采用jsonp

 

11. Websocket的详细原理

1.全双工通信

过程分为握手+数据通信。

客户端:

GET /webfin/websocket/ HTTP/1.1

Host: localhost

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==

Origin: http://localhost:8080Sec-WebSocket-Version: 13

服务器端:

HTTP/1.1 101 

Switching Protocols 

Upgrade: websocket

 Connection: Upgrade

Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=

 

 

12. 浏览器的缓存

浏览器缓存:强缓存和协商缓存

强缓存:在浏览器请求数据时,会判断时间是否过期,来进行判断。如果过期才发送请求,没有的话,则采用本地的数据

协商缓存:浏览器决定不了,必须向服务器请求,交由浏览器判断。对于协商缓存来说,请求是必须要发的,但服务端判定客户端可以使用缓存时,就不会返回响应体了,体现在响应头中就是 304

使用场景:

当新打开一个 Tab 来加载网页,或者在当前 Tab 输入新的 url 加载新网页时,此时浏览器的内存缓存就没有使用场景了,缓存策略就是根据相关 header 字段来决定是走强缓存还是协商缓存

F5 刷新页面时,如果允许缓存,那么会优先从内存缓存中寻找,再根据 header 字段来判断走强缓存还是协商缓存

Ctrl + F5 也叫强制刷新,此时发给服务端的请求头中不会携带 If-Modified-Since ETag 字段,那么服务端自然只能重新下发资源

 

 

缓存位置:

1. Service Worker 

Service Worker 的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的

采用的协议为https

2.  Memory Cache 内存缓存

高效性,但是缓存时间短,tab丢失就会失去缓存。当访问过页面以后,一般再次刷新页面就会来源于内存缓存。Placeholder指令一般是一边解析JS一边请求服务器的资源。

内存缓存在缓存资源时并不关心返回资源的HTTP缓存头Cache-Control是什么值,同时资源的匹配也并非仅仅是对URL做匹配,还可能会对Content-Type,CORS等其他特征做校验

3.  Disk Cache 硬盘存储

在所有的缓存中,覆盖面是最大的,存储大文件时使用硬盘存储。根据httpHeader进行判断。

4. Push Cache 推送缓存

它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存时间也很短暂

强缓存

在控制台中返回200的状态码,并且sizefrom disk cachefrom memory cache

Expires:  缓存的过期时间,以本地时间为准。http1.0

Cache-control: publicpriviatemax-ageno-cache:客户端缓存内容no-store:所有内容都不会被缓存 http1.1,优先于Expires

协商缓存:

Last-Modified/If-Modified-Since:  最后一次修改时间(缺点:以秒计时)

ETagIf-None-Match服务器响应的唯一标识,只要资源有变则会重新生成。请求时将Etag的值放在请求头的if-None-Match

13. sessioncookie的区别

Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;
Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。

Cookie:

原因:起初是因为http是无状态的,服务器是有状态的,则为了存储web中的状态信息,以方便服务器端使用。现在可以保存登录信息、个人信息等。

过程:

服务器像客户端发送cookie

浏览器将cookie保存

之后每次http请求浏览器都会将cookie发送给服务器端

缺点:大小4KB,一般用于服务器给浏览器的一个标识。有CSRF的安全隐患。存储信息的安全性不好。在同源的http请求中,每次都携带。会浪费带宽。

sessionStoragelocalStorage

localStorage生命周期是永久,这意味着除非用户显示在浏览器提供的UI上清除localStorage信息,否则这些信息将永远存在。

sessionStorage生命周期为当前窗口或标签页,一旦窗口或标签页被永久关闭了,那么所有通过sessionStorage存储的数据也就被清空了。

共同点:保存的大小都为5MB

14. this

谁调用,函数就指向谁。

情况一:普通函数调用,则指向全局window

情况二:对象调用,则指向对象

情况三:构造函数使用,则指向实例

情况四:箭头函数中的this,指的是父级的上下文

 

15. 事件委托

定义:事件目标(子元素)不处理事件,把事件委托给父元素去处理。

 

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);
    }
  }
}

先找到相对应的节点,然后e.target.nodeName进行判断,然后做出相应的事件。

适合用事件委托的事件clickmousedownmouseupkeydownkeyupkeypress

注册事件的方法addEventListener(事件类型,函数体,默认为false,事件发生在捕获阶段,true发生在冒泡阶段)  

attachEvent()支持IE678  

直接获取对象.onclick事件

 

事件委托的优点:

提高性能:每一个函数都会占用内存空间,只需添加一个事件处理程序代理所有事件,所占用的内存空间更少。

动态监听:使用事件委托可以自动绑定动态添加的元素,即新增的节点不需要主动添加也可以一样具有和其他元素一样的事件。
js中事件传播的三个阶段:捕获阶段,目标阶段,冒泡阶段;

 

16. 阻止事件冒泡和阻止事件的默认行为

事件传播的阻止方法:

W3C中,使用stopPropagation()方法。

IE下使用cancelBubble = true方法。


阻止默认行为:

W3c中,使用preventDefault()方法。

IEreturn false

 

事件对象兼容IE的写法e||window.event;

事件源对象的兼容性写法event.target||event.Element

17. 浏览器的跨域问题

18. 节点的增删改查

元素节点:

1.通过元素的id来获取相应的节点 document.getElementById("");

2.通过元素的标签名来获取节点 document.getElementsByTagName("");

3.通过元素的类名来获取节点 document.getElementsByClassName("");

4.通过元素的name属性来获取节点 document.getElementsByName("");

5.获取元素的所有子节点 node.childNodes;

6.创建元素节点 document.createElement("tagName");

7.往父节点最后添加子节点 fatherNode.append(childNode);

8.删除元素节点 fatherNode.removeChild(childNode);

9.替换节点 fatherNode.replaceChidl(newNode,oldNode);

 

属性节点:

1.添加属性节点 node.setAttribute('attr',"attrValue");

2.删除属性节点 div.removeAttribute("attr");

3.修改属性节点 div.setAttribute("attr","new");

4.获取属性节点 div.getAttribute("style");

 

文本节点:

1.创建文本节点 var textNode = document.createTextNode("hello");

2.获取文本节点 var textNode = div.childNodes[0];

3.删除起始位置开始的num个值 textNode.deleteData(starNum,num);

4.尾部添加内容 textNode.appendData("后面哦");

5.中间插入内容 te.insertData(1,"中间哦");

查找:

querySelector()querySelectorAll()

 

 

 

19. 单页应用与多页应用的区别

单页应用:只有一个WEB主页面的应用,公共资源(jscss)仅需加载一次,所有的内容都包含在主页面,对每一个功能模块组件化。单页应用跳转,就是切换相关组件,仅刷新局部资源。常用于PC端官网、购物等网站。

多页应用:有多个独立的页面的应用,每个公共资源(jscss)需选择性重新加载,多页面跳转刷新所有资源。常用于 app 或 客户端等。

可分为传统的应用模式和单页面形式。

传统的模式通过URL进行页面的切换,单页面形式。

 

单页应用出现首屏加载缓慢,解决方法:

  1. 路由懒加载、图片的懒加载
  2. Ui框架按需加载
  3. Gzip压缩,配置
  4. 图片压缩
  5. 使用CDN静态加载
  6. 预渲染
  7. 骨架屏 puppeteer
  8. 去掉map文件
  9. 浏览器缓存

20. 组件化和模块化的区别

组件化:将代码重复的部分提取出来,合成一个组件。

模块化:按照功能进行划分,将相同功能的部分提取到一起,形成一个模块。

组件相当于库,把一些能在项目里或者不同类型项目中可复用的代码进行工具性的封装。

模块相应于业务逻辑模块,把同一类型项目里的功能逻辑进行进行需求性的封装。

21. js的内置对象有哪些?

  1. 值属性:InfinityNaNnullundefined
  2. 函数属性:eval()parseFloat()parseInt()
  3. 基本对象:ObjectFunctionBooleanError
  4. 数字和日期对象
  5. 字符串
  6. 可索引的集合对象
  7. 使用键的集合对象
  8. 矢量集合
  9. 结构化数据,如JSON
  10. PromiseReflectProxy
  11. arguments

22. Valueof()toString()

{}valueof()结果是{},toString的结果是[Object object]

[]valueof()结果是[],toString的结果是’’

23. Js中获取原型的方法

p.proto

p.constructor.prototype

Object.getPrototypeOf()

24. 三种事件模型

DOM0级模型、IE事件模型、DOM2级事件模型

25. js的延迟加载

  1. js放在文档的底部
  2. 添加defer属性,脚本的加载与文档的解析同步,然后在文档解析完执行脚本
  3. Async 异步加载,会在脚本执行完之后执行js
  4. 动态创建DOM标签,对文档进行事件监听,当文档加载完在动态创建script标签。

26. V8引擎的垃圾回收机制

分代回收机制:新生代和老生代表。FromTo两个空间。

老生代采用标记清除和引用计数法。

27. 造成内存泄露的操作和内存泄露后的方法

操作:1.  意外的全局变量

  1. 被遗忘的定时器或回调函数
  2. 脱离DOM的使用
  3. 闭包

方法:1.  利用chorme的插件进行分析内存占用情况

  1. 在退出函数前将不使用的变量删除
  2. 避免变量的循环赋值和引用
  3. 定时器
  4. 回调
  5. 函数的防抖节流
  6. 封装私有变量
  7. 函数柯里化
  8. 不使用循环返回数组

28. 闭包的使用场景

29. 写一个通用的事件侦听器函数

const EventUtils = {

  // 视能力分别使用dom0||dom2||IE方式 来绑定事件

  // 添加事件

  addEvent: function(element, type, handler) {

    if (element.addEventListener) {

      element.addEventListener(type, handler, false);

    } else if (element.attachEvent) {

      element.attachEvent("on" + type, handler);

    } else {

      element["on" + type] = handler;

    }

  },

 

  // 移除事件

  removeEvent: function(element, type, handler) {

    if (element.removeEventListener) {

      element.removeEventListener(type, handler, false);

    } else if (element.detachEvent) {

      element.detachEvent("on" + type, handler);

    } else {

      element["on" + type] = null;

    }

  },

 

  // 获取事件目标

  getTarget: function(event) {

    return event.target || event.srcElement;

  },

 

  // 获取 event 对象的引用,取到事件的所有信息,确保随时能使用 event

  getEvent: function(event) {

    return event || window.event;

  },

 

  // 阻止事件(主要是事件冒泡,因为 IE 不支持事件捕获)

  stopPropagation: function(event) {

    if (event.stopPropagation) {

      event.stopPropagation();

    } else {

      event.cancelBubble = true;

    }

  },

 

  // 取消事件的默认行为

  preventDefault: function(event) {

    if (event.preventDefault) {

      event.preventDefault();

    } else {

      event.returnValue = false;

    }

  }

};

30. 手动实现Array.prototype.map方法

function map(arr, mapCallback) {

  // 首先,检查传递的参数是否正确。

  if (!Array.isArray(arr) || !arr.length || typeof mapCallback !== 'function') { 

    return [];

  } else {

    let result = [];

    // 每次调用此函数时,我们都会创建一个 result 数组

    // 因为我们不想改变原始数组。

    for (let i = 0, len = arr.length; i < len; i++) {

      result.push(mapCallback(arr[i], i, arr)); 

      // 将 mapCallback 返回的结果 push 到 result 数组中

    }

    return result;

  }

}

31. 手动书写promise

function myPromise(constructor){

    let self=this;

    self.status="pending" //定义状态改变前的初始状态

    self.value=undefined;//定义状态为resolved的时候的状态

    self.reason=undefined;//定义状态为rejected的时候的状态

    function resolve(value){

        //两个==="pending",保证了状态的改变是不可逆的

       if(self.status==="pending"){

          self.value=value;

          self.status="resolved";

       }

    }

    function reject(reason){

        //两个==="pending",保证了状态的改变是不可逆的

       if(self.status==="pending"){

          self.reason=reason;

          self.status="rejected";

       }

    }

    //捕获构造异常

    try{

       constructor(resolve,reject);

    }catch(e){

       reject(e);

    }

}

// 定义链式调用的then方法

myPromise.prototype.then=function(onFullfilled,onRejected){

   let self=this;

   switch(self.status){

      case "resolved":

        onFullfilled(self.value);

        break;

      case "rejected":

        onRejected(self.reason);

        break;

      default:       

   }

}

32. instanceof的原理

  1. 首先获取类型的原型
  2. 然后获取对象的原型
  3. 然后一直循环判断对象的原型是否等于类型的原型,直到找到。

33.原型与原型链

js中,对象都有__proto__属性,一般这个是被称为隐式的原型,该隐式原型指向构造该对象的构造函数的原型。

  函数比较特殊,它除了和其他对象一样有__proto__属性,还有自己特有的属性----prototype,这个属性是一个指针,指向一个包含所有实例共享的属性和方法的对象,称之为原型对象。原型对象也有一个constructor属性,该属性指回该函数。

 

 

 

33. 判断数组的方法

  1. Array.isArray();
  2. A.constructor.name==’Array’
  3. Object.prototype.toString.call(a)===”[Object Array]”
  4. a instanceof Array
  5. A.__proto__==Array.prototyoe

   

 

 

 

 

 

 

 

 

 

 

二、CSS

 

1. 引入css的方式及其特点。

  1. 行内式
  2. 内嵌式
  3. 导入式:@import方式导入CSS文件,有两种导入方式 :在style内部导入、在css中导入。
  4. 链接式:link

 @importlink的区别:

区别1link属于XHTML标签,而@import完全是CSS提供的一种方式。

区别2:加载顺序的差别。当一个页面被加载的时候(就是被浏览者浏览的时候),link引用的CSS会同时被加载,而@import引用的CSS 会等到页面全部被下载完再被加载。

区别3:兼容性的差别。由于@importCSS2.1提出的所以老的浏览器不支持,@import只有在IE5以上的才能识别,而link标签无此问题。

区别4:使用dom控制样式时的差别。当使用javascript控制dom去改变样式的时候,只能使用link标签,因为@import不是dom可以控制的。

2. 优先级别,怎样将级别弄成一样的。

(1)内联,如style=”“——1000,
2)id,如#content——100,
3)类、伪类和属性选择器,如.content——10,
4)标签选择器和伪元素选择器,如div p——1
5)通配符、子选择器和相邻选择器,如*,>,+——0

 

3. 盒模型

标准盒模型和IE盒模型(宽度包括content + padding +border)

box-sizingcontent-box标准盒模型

 

4. 垂直水平居中

方法有4种:

  1. flex布局
  2. 绝对位置,top:0,right:0,left:0,bottom:0,margin:auto
  3. 绝对位置,left:50%,top:50%,margin-left:负元素宽度的一半
  4. 子绝父相,left:50%,top:50%,transform:translate(-50%,-50%)
  5. 父级设置text-align:center

.container {

  position: fixed;

  top: 0;

  right: 0;

  bottom: 0;

  left: 0;

  background: rgba(0, 0, 0, 0.5);

  text-align: center;

  font-size: 0;

  white-space: nowrap;

  overflow: auto;

}

.container::after {

  content: "";

  display: inline-block;

  height: 100%;

  vertical-align: middle;

}

.box {

  display: inline-block;

  width: 500px;

  height: 400px;

  

  white-space: normal;

  vertical-align: middle;

 

5. 如何创建BFC IFC

  • 1、float的值不是none。
  • 2、position的值不是static或者relative。
  • 3、display的值是inline-block、table-cell、flex、table-caption或者inline-flex
  • 4、overflow的值不是visible

BFC的作用:

1.利用BFC避免margin重叠,外边距重叠

2.自适应两栏布局

3.清除浮动

 

IFC:行级格式化上下文

局规则如下:
1.内部的盒子会在水平方向,一个个地放置;
2.IFC的高度,由里面最高盒子的高度决定;
3.当一行不够放置的时候会自动切换到下一行;

 

6. 重绘和重排

会影响重排和重绘的CSS属性有background-color,box-shadow,display,height

动画开始不要使用dispaly:none

translate属性值来替换top/left/right/bottom的切换,scale属性值替换width/heightopacity属性替换display/visibility等等

  1. 批量修改
  2. 缓存布局信息

7. Width:autowidth:100%的区别

Width:100% 宽度等于父元素的contentbox

Width:auto  宽度会撑满整个父元素,margin,border,padding,contnet会自动分配空间。

8. 一个自适应矩形,高为宽的2倍,水平垂直居中

利用position:absolute left:0,top:0,bottom:0,right:0 margin:auto width:10% height:0 padding-top:20%,background:#eee;

9. 实现一个宽高自适应的正方形

方法1:利用padding-top  

方法2:宽度10%高度10vw

方法3:利用父元素的overflow:hidden 子元素的content:’’,display:block,margin-top:100%

10. 三栏布局

方法1:采用绝对定位 中间的用margin

方法2:采用flex布局,中间flex:auto

方法3:采用浮动,左右分别为左右浮动

方法4:圣杯布局,父级设置padding,中间设置为父级的宽度,三个都左浮动,通过负边距

.main>div{ float: left; }

 .left { width: 200px; background: red; margin-left: -100%; }

.right{ width: 200px; background: blue; margin-left: -200px; }

.middle{ width: 100%; background: yellow; }

.content{ margin-left: 200px; margin-right: 200px; }

方法5:双飞翼布局,通过中间的margin来进行布局。

.main{ height: 200px; padding: 0 150px 0 200px; background: greenyellow; *zoom: 1; }

.left , .center , .right{ float: left; }

 .center{ width: 100%; height: 200px; background: red; }

.left { width: 200px; height: 200px; background: yellow; margin-left: -100%; position: relative; left: -200px; }

.right{ width: 150px; height: 200px; background: gainsboro; margin-left: -150px; position: relative; left: 150px;}

11. css隐藏的8种方法

1.overflow:hidden
2.opacity:0;
3.visibility:hidden
4.display:none
5.position:absolute
6.clip(clip-path):rect()/inset()/polygon()
7.z-index:-1000
8.transform:scaleY(0)

 

12. Line-height150%line-height=1.5区别

150%是根据父元素计算子元素的行高,1.5是根据子元素计算子元素的行高

13. 什么是幽灵空白节点?

每个行框盒子的前面有一个“空白节点”一样。

14. min-width/max-width min-height/max-height 属性间的覆盖规则?

1max-width会覆盖width,即使width是行类样式或者设置了!important

 

(2)min-width会覆盖max-width,此规则发生在min-widthmax-width冲突的时候。

15. 画一条 0.5px 的线

采用metaviewport的方式

 

采用border-image的方式

 

采用transform:scale()的方式

16.style 标签写在 body 后与 body 前有什么区别?

页面加载自上而下当然是先加载样式。写在body标签后由于浏览器以逐行方式对HTML文档进行解析,当解析到写在尾部的样式

表(外联或写在style标签)会导致浏览器停止之前的渲染,等待加载且解析样式表完成之后重新渲染,在windowsIE下可

能会出现FOUC现象(即样式失效导致的页面闪烁问题)

17.pngjpggif 这些图片格式解释一下,分别什么时候用。有没有了解过 webp

1BMPBMP格式的图片通常具有较大的文件大小。

2GIF适用于对色彩要求不高同时需要文件体积较小的场景。

3JPEG适合用来存储照片,与GIF相比,JPEG不适合用来存储企业Logo、线框类的图。

4PNG-8

5PNG-24

6SVG适合用来绘制企业LogoIcon等。

7WebP相同质量的图片,WebP具有更小的文件体积。

但是目前只有Chrome浏览器和Opera浏览器支持WebP格式,兼容性不太好。

18.如何让去除 inline-block 元素间间距?

移除空格、使用margin负值、使用font-size:0letter-spacingword-spacing

19. 移动端的适配

设备像素比:device pixel ratiodpr   DPR = 设备像素 / 设备独立像素

ppI像素密度:

PC端的尺寸:

screen.width指的是我们显示器的水平方向的像素时,不随着我们浏览器窗口的变化而变化,是用设备像素衡量的

window.innerWidth指的是浏览器窗口的宽度

document.documentElement.clientWidth指的是viewport的宽度,与window.innerWidth的区别就只差了一个滚动条

document.documentElement.offsetWidth指的是html的宽度,默认为浏览器窗口的宽度

移动端的尺寸:

layout viewportIOSlayout viewport默认大小980px,在androidlayout viewport800px

visual viewport:浏览器可视区域的大小

ideal viewport:设备理想的viewport,用户不用放大或者缩小就能看到所有信息。

 

 

 

20. CSSall

所有的CSS属性的缩写,设计到的属性很多很多。

21. 绝对定位元素与非绝对定位元素的百分比计算的区别

绝对定位元素的宽高百分比是相对于临近的position不为static的祖先元素的paddingbox来计算的。

非绝对定位元素的宽高百分比则是相对于父元素的contentbox来计算的。

22. cssvisibitily:collapse

在谷歌浏览器里,使用collapse值和使用hidden值没有什么区别。

在火狐浏览器、OperaIE11里,使用collapse值的效果就如它的字面意思:table的行会消失,它的下面一行会补充它的位置。

  1. Css中有继承的属性

有继承性的属性:

 

1)字体系列属性fontfont-familyfont-weightfont-sizefont-stylefont-variantfont-stretchfont-size-adjust

 

2)文本系列属性text-indenttext-aligntext-shadowline-heightword-spacingletter-spacingtext-transformdirectioncolor

 

3)表格布局属性caption-sideborder-collapseempty-cells

 

4)列表属性list-style-typelist-style-imagelist-style-positionlist-style

 

5)光标属性cursor

 

6)元素可见性visibility

 

7)还有一些不常用的;speakpage,设置嵌套引用的引号类型quotes等属性

23.margin塌陷问题

问题描述:

在文档流中,父元素的高度默认是被子元素撑开的

也就是说 子元素有多高,父元素就有多高

但是当子元素设置浮动之后,子元素会完全脱离文档流

此时将会导致子元素无法撑开父元素的高度,导致父元素高度塌陷

解决方法:触发BFC

触发BFC的方式有

1.浮动元素   float属性值为除了none以外的值

2.绝对定位元素 position absolutefixed

3.display inline-blocks,table-cells,table-captions

4.overflow hidden,auto,scroll

 

两个div套在一块,外边的没有设置任何样式,里边设置margin-top,会导致塌陷,外层盒子的位置在100px上。

 

24. margin合并(垂直方向上的两个块级元素)

  1. 两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
  2. 两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
  3. 两个外边距一正一负时,折叠结果是两者的相加的和。

25. 清除浮动的方法 (清除浮动主要是为了解决,父元素因为子级元素浮动引起的内部高度为0的问题)

1)父级div定义height

2)结尾处加空div标签,样式clear:both

3)父级div定义伪类:afterzoom

4)父级div定义overflow:hidden(同时还要定义widthzoom:1,不能定义height

5)父级div定义overflow:auto(同时还要定义widthzoom:1,不能定义height

6)父级也浮动,需要定义width(不推荐)

7)父级div定义displaytable(不推荐)

8)结尾处加br标签,样式clear:both(父元素div定义zoom:1,不推荐)

26. css选择器

 

27. Srchref的区别

href (Hypertext Reference)指定网络资源的位置,从而在当前元素或者当前文档和由当前属性定义的需要的锚点或资源之间定义一个链接或者关系。

source(缩写),指向外部资源的位置,指向的内容将会应用到文档中当前标签所在位置。

区别:

1.请求资源类型不同

1href 指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的联系。

2)在请求 src 资源时会将其指向的资源下载并应用到文档中,比如 JavaScript 脚本,img 图片;

2 作用结果不同

1href 用于在当前文档和引用资源之间确立联系;

2src 用于替换当前内容;

3 浏览器解析方式不同

1)若在文档中添加 ,浏览器会识别该文档为 CSS 文件,就会并行下载资源并且不会停止对当前文档的处理。这也是为什么建议使用 link 方式加载 CSS,而不是使用 @import 方式。

2)当浏览器解析到 ,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等也如此,类似于将所指向资源应用到当前内容。这也是为什么建议把 js 脚本放在底部而不是头部的原因。

 

28. 怎么让 Chrome 支持小于 12px 的文字?

方式1-webkit-text-size-adjust:none;

方式2-webkit-transform:scale(0.5);注意-webkit-transform:scale(0.75);收缩的是整个元素的大小,这时候,如果是内联元素,必须要将内联元素转换成块元素,可以使用displayblock/inline-block/...

方式3:使用图片:如果是内容固定不变情况下,使用将小于12px文字内容切出做图片,这样不影响兼容也不影响美观。

29. 使用rem布局

通过js动态获取手机的DPR,然后通过dpr来动态设置 html  font-size,以及设置缩放比例。

30. 两栏布局的方法及优缺点

  1. float布局

① Margin-left     

② Overflow:hidden

  1. 定位布局

  Position:absolute right:0 top:0 left:宽度

  1. flex布局

  左边固定宽度,右边flex:1

  1. table布局

   父级display:table  子级:display:table-cell

  1. grid网格布局

   display: grid; grid-template-columns: 200px auto; /*设置每一列的宽度,200px,右自适应*/

 

31. 三栏布局的方法及优缺点

  1. 采用浮动,左浮动和右浮动
  2. 采用绝对定位,左边left:0,右边right:0   

 缺点:绝对定位是脱离文档流的,意味着下面的所有子元素也会脱离文档流,这就导致了这种方法的有效性和可使用性是比较差的。

  1. Flex布局

缺点:felxbox的缺点就是不能兼容IE8及以下浏览器。

  1. 表格布局

缺点:当其中一个单元格高度超出的时候,两侧的单元格也是会跟着一起变高的,而有时候这种效果不是我们想要的。

  1. 网格布局

display: grid; grid-template-rows: 100px; grid-template-columns: 300px auto 300px;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

三、VUE

1. 双向绑定原理

Object.defineProperty(obj, prop, descriptor)

  参数:

obj:必需。目标对象;
  prop:必需。需定义或修改的属性的名字;
  descriptor:必需。目标属性所拥有的特性;

首先我们为每个vue属性用Object.defineProperty()实现数据劫持,为每个属性分配一个订阅者集合的管理数组dep;

  然后在编译的时候在该属性的数组dep中添加订阅者,v-model会添加一个订阅者,{{}}也会,v-bind也会,只要用到该属性的指令理论上都会;

接着为input会添加监听事件,修改值就等于为该属性赋值,则会触发该属性的set方法,在set方法内通知订阅者数组dep,订阅者数组循环调用各订阅者的update方法更新视图。

 

2. 生命周期函数

beforeCreate : 创建Vue实例前的时候执行

created :  创建Vue实例完成后执行,属性DOM还未绑定完成。

beforeMount : Vue实例开始渲染前执行,已经生成render函数。

mounted  :  Vue实例渲染完成后执行,可访问DOM,el$el替换。

beforeUpdate  :  Vue实例修改前执行,

updated  :  Vue实例修改完成后执行,

beforeDestroy  : Vue开始消亡前执行,

destroyed  : Vue实例消亡后执行,

activated  :组件激活时调用。该钩子在服务器端渲染期间不被调用。

deactivated    组件停用时调用。该钩子在服务器端渲染期间不被调用。

errorCaptured  :   当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止

 

3. Keep-alive该怎么使用

keep-alive  我们常在列表页使用,比如我们在业务上经常会有要求,当查看完某一列表详情页时,返回列表页,需要回到原来的位置,并保持页面的状态。

include 值为字符串或者正则表达式匹配的组件name会被缓存。

exclude 值为字符串或正则表达式匹配的组件name不会被缓存

路由中的meta定义,根据判断是否为true来进行缓存。

4. 组件之间传参

父子之间:props$emit

$refs$parent $children

Provide project

-子:子组件$listenersemits事件除外)、$attrs(props除外)

无关系兄弟之间:BUS this.$root.bus.$emit(‘’,1) this.$root.bus.on

5. deletevue.$delete的区别

delte会删除数组的值,但是它依然会在内存中占位置
vue.delete会删除数组在内存中的占位

vue.delete可以避免vue检测不到新的property

 

6. vue中如何自定义事件

使用 $on(eventName) 监听事件,在父组件里监听

使用 $emit(eventName) 触发事件,在子组件里触发

.sync事件修饰符,实现对props传递数据的双向绑定,一般用于模态框的关闭。

7. 插槽

具名插槽: 父组件通过 v-slot:[name] 的方式指定到对应的插槽中。

 

作用域插槽:作用域插槽其实就是带数据的插槽,即带参数的插槽,简单的来说就是子组件提供给父组件的参数,该参数仅限于插槽中使用,父组件可根据子组件传过来的插槽数据来进行不同的方式展现和填充插槽内容。

<template v-slot:default="slotProps">

8. 插件

开发时Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:

使用插件:通过全局方法 Vue.use() 使用插件。

9. 自定义指令

// 注册一个全局自定义指令 `v-focus` 

Vue.directive('focus',

{ // 当被绑定的元素插入到 DOM 中时……

 inserted: function (el)

{ // 聚焦元素

 el.focus() }

})

10. Vue 不能检测到对象属性的添加或删除,无法检测数组/对象的新增,无法检测通过索引改变数组的操作,无法修改数组的长度。

原因:对于对象来说,是刚开始没有定义相对应的属性,所以没有响应式

      对于数组来说,源码上对数组进行监听,但是当数据类型为数组时没有监听,导致无法修改修改数组的长度,修改源码进行监听,则可以改变,但是数组循环会调用很多次,对性能来说不好(尤大大)。

ProxydefineProperty相比较,一个是对对象的属性进行监听,一个是对数组进行拦截。改变属性值通过observer进行操作,而proxy13种拦截对象,对对象和属性进行操作拦截。但是proxy的兼容性不好,特别是针对ie

11.为啥data是一个函数?

 vue组件中data值不能为对象,因为对象是引用类型,组件可能会被多个实例同时引用。如果data值为对象,将导致多个实例共享一个对象,其中一个组件改变data属性值,其它实例也会受到影响。

 

data为函数,通过return 返回对象的拷贝,致使每个实例都有自己独立的对象,实例之间可以互不影响的改变data属性值。

 

四、ES6

1. setweakSet

它类似于数组,但是成员的值都是唯一的,没有重复的值。Set本身是一个构造函数,用来生成Set数据结构。

Set加入值的时候,不会发生类型转换

add(value):添加某个值,返回Set结构本身。

delete(value):删除某个值,返回一个布尔值,表示删除是否成功。

has(value):返回一个布尔值,便是该值是否为Set成员。

clear():清除所有成员,没有返回值。

 


keys():返回键名的遍历器

values():返回键值的遍历器

entries():返回键值对的遍历器

forEach():使用回调函数遍历每个成员

WeakSet区别:

第一个:WeakSet的成员只能是对象,而不能是其他的值。

第二个:WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说,如果其他对象都不再引用该对象。那么垃圾回收机制会自动会输该对象所占用的额内存,不考虑该对象还存在与WeakSet之中。

 WeakSet没有size属性,没有办法遍历它的成员。

2. MapweakMap

Map类似数组,但“键”的范围不限于字符串,各种类型都可以,size属性

WeakMap

WeakMap对象是一组键值对的集合,其中的键是弱引用的,必须为对象,而值可以是任意的。

3. 扩展运算符的原理

数组采用数组的方法[].contact

对象采用内置的属性函数将其拷贝出来。

4.promise.all的实现

/** 仅考虑 promises 传入的是数组的情况时 */

Promise.all = function (promise) {

let promises = Array.from(promise)//将iterator转换为数组

    return new Promise((resolve, reject) => {

        if (promises.length === 0) {//如果数组长度为0则返回空数组

            resolve([]);

        } else {

            let result = [];//存放已成功的异步操作

            let index = 0;//记录已成功的操作数

            for (let i = 0;  i < promises.length; i++ ) {

                Promise.resolve(promises[i])//执行每一个promise

                 .then(data => {

                     result[i] = data;

                     if (++index === promises.length) {

                        //所有的 promises 状态都是 fulfilled,promise.all返回的实例才变成 fulfilled 态

                         resolve(result);

                    }

                }, err => {

                    reject(err);

                    return;

                });

            }

        }

    });}

Promise.race()实现

var race = function(promise) {

let promises = Array.from(promise)

    return new Promise(function(resolve, reject) {

        for (var i = 0; i < promises.length; i++) {

         Promise.resolve(promises[i]).then(data => {

resolve(data);

         }, err => {

           return reject(err)

        })

      }

    })

  }

 

5.解构赋值是深拷贝还是浅拷贝

深拷贝:修改新变量的值不会影响原有变量的值。默认情况下基本数据类型都是深拷贝。
浅拷贝:修改新变量的值会影响原有的变量的值。默认情况下引用类型都是浅拷贝。

  1. 解构赋值对object类型只是浅拷贝。对所有的引用类型都是浅拷贝。
  2. 解构赋值对于基本数据类型是深拷贝。

 

6.CommonJs/ES6/AMD/CMD模块的用法以及区别

CommonJs每个文件都是一个单独的模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。

node.js中使用。引入require,输出exportsCommonJS规范不适用于浏览器环境。

CommonJs的特点

值的拷贝,运行时加载。

1.所有的代码都运行在模块作用域,不会污染全局作用域;

2.模块可以多次加载,但是只会在第一次加载时运行一次,然后运行的结果就会被缓存了,以后再加载就直接读取缓存结果。要想让模块继续运行,必须清空缓存;

3.模块加载顺序,按照其在代码中出现的顺序;

4.CommonJs加载模块是同步的;

ES6模块的设计是尽可能的静态化,使得编译时就能确定模块之间的依赖关系,以及输入和输出变量Importrequire。而CommonJSCMD,都只能在运行时确定依赖。

ES6模块的特点ES6模块的import/export目前不支持在node环境中直接使用。

值的引用,编译时输出接口。

AMD:异步加载模块,模块的加载不影响它后面语句的运行。采用require接收模块。

CMD: CMD全称是Common Module Definition,它整合了CommonJSAMD规范的特点,专门用于浏览器端,异步加载模块。

 

总结

CommonJS规范主要用于服务端编程,加载模块是同步的,这并不适合在浏览器环境,因为同步意味着阻塞加载,浏览器资源是异步加载的,因此有了AMDCMD解决方案。

AMD规范在浏览器环境中异步加载模块,而且可以并行加载多个模块。不过,AMD规范开发成本高,代码的阅读和书写比较困难,模块定义方式的语义不顺畅。

CMD规范与AMD规范很相似,都用于浏览器编程,依赖就近,延迟执行,可以很容易在Node.js中运行。但是依赖SPM打包,模块的加载逻辑偏重。

ES6在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代CommonJSCMD规范,成为浏览器和服务器通用的模块化解决方案。

7.generator(生成器)

function* foo(x) {

    yield x + 1;

    yield x + 2;

    return x + 3;

}

函数调用后并不执行,而是一个指向内部状态的指针对象,通过next()进行调用。Yield暂停执行,下一次从当前位置再往下执行。Return没有记忆则执行下边的。

使用异步的问题中,因为能教出函数的执行权,暂停。

8.Iterator

Iterator(迭代器)是一种接口,也可以说是一种规范。为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

 

Iterator语法:

 

const obj = {

    [Symbol.iterator]:function(){}

}

 

 

[Symbol.iterator] 属性名是固定的写法,只要拥有了该属性的对象,就能够用迭代器的方式进行遍历。

 

迭代器的遍历方法是首先获得一个迭代器的指针,初始时该指针指向第一条数据之前,接着通过调用 next 方法,改变指针的指向,让其指向下一条数据 每一次的 next 都会返回一个对象,该对象有两个属性

 

value 代表想要获取的数据

 

done 布尔值,false表示当前指针指向的数据有值,true表示遍历已经结束

 

Iterator 的作用有三个:

 

为各种数据结构,提供一个统一的、简便的访问接口;

 

使得数据结构的成员能够按某种次序排列;

 

ES6 创造了一种新的遍历命令forof循环,Iterator 接口主要供forof消费。

 

 

 

 

 

五、安全性能相关

1. 性能优化的方式

① 减少http请求,

② 使用HTTP2,多路复用,解析速度快,首部压缩、优先级、流量控制、服务器推送

③ 使用服务器端渲染

④ 静态使用CDN

⑤ CSS放在头部,js放在文件底部

⑥ 使用字体图标iconfont代替图片图标

⑦ 善用缓存,添加Expires头,服务器配置Etag等浏览器缓存、webpack-缓存、

⑧ 压缩文件

 

compression-webpack-pulign压缩成gzip文件

uglifyjs-webpack-pulign 打包时自动删除console.log

体积分析 webpack-bundle-analyzer 插件,

速度分析:speed-measure-webpack-plugin 插件。

Mini-css-webpack-pulign分离css文件

Paraller:true  并行加载

 

⑨ 图片优化(图片延迟加载、降低图片质量通过image-webpack-loader、调整图片大小、响应式图片、尽可能使用CSS3代替图片)

web 前端图片懒加载实现原理

先将img标签的src链接设为同一张图片(比如空白图片),然后给img标签设置自定义属性(比如 data-src,然后将真正的图片地址存储在data-src中,当JS监听到该图片元素进入可视窗口时,将自定义属性中的地址存储到src属性中。达到懒加载的效果。

 

 

⑩ 按需加载,提取第三方代码,进行优化

⑪ 减少重绘重排

⑫ 使用事件委托

⑬ 注意程序的局限性

⑭ 使用requestAnmiationFrame

⑮ 避免使用css表达式,避免使用高级选择器。

 

 

会把静态资源和动态网页分集群部署,静态资源会被部署到CDN节点上,网页中引用的资源也会变成对应的部署路径:

2. 跨域问题(针对浏览器)在本子上

3. 为啥0.1+0.2!==0.3

 Js中的数据存储:双精度64位浮点数表示。

计算机中数字是二进制存储,将0.1转换成0.0 0011 0011..

方法:将其转换成整数进行处理,先乘再除。

4. 动态原理是啥,webpack

webpack 动态加载就两种方式:import() require.ensurejsonP动态加载chunk

 

5. Js中的var变量提升

  • 函数提升优于变量提升执行
  • 变量提升只提升声明,函数提升声明和赋值
  • 变量声明不会覆盖变量或函数的赋值
  • 函数声明会覆盖同名的变量声明和函数赋值,但不会覆盖变量赋值!
  • 立即执行函数(IIFE)中存在局部作用域,变量只会提升到函数内的顶部

6. babel 原理

babel的转译过程分为三个阶段:parsingtransforminggenerating,以ES6代码转译为ES5代码为例,babel转译的具体过程如下:

  1. ES6代码输入
  2. babylon 进行解析得到 AST
  3. plugin babel-traverse AST 树进行遍历转译,得到新的AST
  4. babel-generator 通过 AST 树生成 ES5 代码

怎么转换成AST(抽象语法树)?

词法分析和语法分析。

7. httpTCPsocket

    套接字(socket)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元

为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了套接字(Socket)接口。应用层可以 和传输层通过Socket接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

  1. 正向代理和反向代理

正向代理的用途:

  (1)访问原来无法访问的资源,如google

2)可以做缓存,加速访问资源

  (3)对客户端访问授权,上网进行认证

  (4)代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息

反向代理的作用:

1)保证内网的安全,阻止web攻击,大型网站,通常将反向代理作为公网访问地址,Web服务器是内网

2)负载均衡,通过反向代理服务器来优化网站的负载

9.restFul框架

restful其实就是一套编写接口的协议,协议规定如何编写以及如何设置返回值、状态码等信息。

使用URI来描述资源,使用HtmlJsonXML等格式表现,通过HTTP动词来操作资源来实现状态转化,使用HTTP状态码反映处理结果。

GET :查询资源操作。

POST :新建资源操作,也可以用于更新资源。

PUT :更新资源操作。

DELETE :删除资源操作。

 

 

10.http请求代码

http状态返回代码 1xx(临时响应)
表示临时响应并需要请求者继续执行操作的状态代码。

http状态返回代码 代码   说明
100   (继续)请求者应当继续提出请求。服务器返回此代码表示已收到请求的第一部分,正在等待其余部分。 
101   (切换协议)请求者已要求服务器切换协议,服务器已确认并准备切换。

http状态返回代码 2xx (成功)
表示成功处理了请求的状态代码。

http状态返回代码 代码   说明
200   (成功)  服务器已成功处理了请求。通常,这表示服务器提供了请求的网页。
201   (已创建)  请求成功并且服务器创建了新的资源。
202   (已接受)  服务器已接受请求,但尚未处理。
203   (非授权信息)  服务器已成功处理了请求,但返回的信息可能来自另一来源。
204   (无内容)  服务器成功处理了请求,但没有返回任何内容。
205   (重置内容)服务器成功处理了请求,但没有返回任何内容。
206   (部分内容)  服务器成功处理了部分 GET 请求。

http状态返回代码 3xx (重定向)
表示要完成请求,需要进一步操作。通常,这些状态代码用来重定向。

http状态返回代码 代码   说明
300   (多种选择)  针对请求,服务器可执行多种操作。服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301   (永久移动)  请求的网页已永久移动到新位置。服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302   (临时移动)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303   (查看其他位置)请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。

304   (未修改)自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。
305   (使用代理)请求者只能使用代理访问请求的网页。如果服务器返回此响应,还表示请求者应使用代理。
307   (临时重定向)  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

http状态返回代码 4xx(请求错误)
这些状态代码表示请求可能出错,妨碍了服务器的处理。

http状态返回代码 代码   说明
400   (错误请求)服务器不理解请求的语法。
401   (未授权)请求要求身份验证。对于需要登录的网页,服务器可能返回此响应。
403   (禁止)服务器拒绝请求。
404   (未找到)服务器找不到请求的网页。
405   (方法禁用)禁用请求中指定的方法。
406   (不接受)无法使用请求的内容特性响应请求的网页。
407   (需要代理授权)此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408   (请求超时)  服务器等候请求时发生超时。
409   (冲突)  服务器在完成请求时发生冲突。服务器必须在响应中包含有关冲突的信息。
410   (已删除)  如果请求的资源已永久删除,服务器就会返回此响应。
411   (需要有效长度)服务器不接受不含有效内容长度标头字段的请求。
412   (未满足前提条件)服务器未满足请求者在请求中设置的其中一个前提条件。
413   (请求实体过大)服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414   (请求的 URI 过长)请求的 URI(通常为网址)过长,服务器无法处理。
415   (不支持的媒体类型)请求的格式不受请求页面的支持。
416   (请求范围不符合要求)如果页面无法提供请求的范围,则服务器会返回此状态代码。
417   (未满足期望值)服务器未满足"期望"请求标头字段的要求。

http状态返回代码 5xx(服务器错误)
这些状态代码表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,而不是请求出错。

http状态返回代码 代码   说明
500   (服务器内部错误)  服务器遇到错误,无法完成请求。
501   (尚未实施)服务器不具备完成请求的功能。例如,服务器无法识别请求方法时可能会返回此代码。
502   (错误网关)服务器作为网关或代理,从上游服务器收到无效响应。
503   (服务不可用)服务器目前无法使用(由于超载或停机维护)。通常,这只是暂时状态。
504   (网关超时)  服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505   (HTTP 版本不受支持)服务器不支持请求中所用的 HTTP 协议版本。 

11.sessionStoragelocalStoragecookie的区别

1)相同点是都是保存在浏览器端、且同源的
2)cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
3)存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
4)数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
5)作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
6)web Storage支持事件通知机制,可以将数据更新的通知发送给监听者
7)web Storage的api接口使用更方便

12.webpack的优化方式

分为两方面:

  1. 提升开发效率

① 减少体积

② 模块热更新

  1. 构建体积优化

① 生产中的sourceMap模式

② 独立的CSS文件 mini-css-extract-plugin

③ 压缩htmlcssjs文件 html-webpack-plugin  optimize-css-assets-webpack-plugin

④ 合并压缩图片(base64转换、image-webpack-loader)

⑤ 依赖库分离(optimization.splitChunks)

⑥ 依赖分析(webpack-bundle-analyzer)

⑦ 按需加载(require.ensure())

⑧ 删除冗余代码

  1. 构建速度的优化

① babel-loader构建时间过长(限制加载器的作用范围、缓存加载器执行结果)

② Resolve优化(尽量少使用别名、文件路径写全)

13. 暂时性死区

在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为暂时性死区

14.async/await的优缺点

优点:代码更加清晰

缺点:滥用 await 可能会导致性能问题,因为 await 会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成,导致代码失去了并发性。

14. 安全问题

跨站脚本攻击(XSS攻击):恶意攻击者在网站中输入script,从而对网站进行攻击。

 常见的场景:1、盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号

2、控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力

3、盗窃企业重要的具有商业价值的资料

4、非法转账

5、强制发送电子邮件

6、网站挂马

7、控制受害者机器向其它网站发起攻击


防范方法:

① 输入校验

② Cookie与系统ip进行绑定

③ 尽量采用postGET

④ 验证码

⑤ HttpOnly Cookie。

⑥ WAF(Web Application Firewall)Web应用防火墙

 

CSRF(Cross Site Request Forgery),即跨站请求伪造仿造用户完成指定的工作,知道用户的信息cookie,密码等信息。

常见的场景: 转账

防御方法:

1) 客户端随机增加伪随机数

2) 验证码

3) Anti-CSRF-Token,即发送请求时在HTTP 请求中以参数的形式加入一个随机产生的token。

SQL注入攻击:攻击者将SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

 

常见的场景:通过注入SQL语句,可通过无账号密码就可以登录网站。获取得到管理员权限。

防范方法:

1、增加黑名单或者白名单验证
白名单验证一般指,检查用户输入是否是符合预期的类型、长度、数值范围或者其他格式标准。黑名单验证是指,若在用户输入中,包含明显的恶意内容则拒绝该条用户请求。在使用白名单验证时,一般会配合黑名单验证。

2、安全检测
在项目完成的时候,始终坚持安全检测。

3、防止系统敏感信息泄露


文件上传漏洞:由于文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者向某个可通过 Web 访问的目录上传任意PHP文件,并能够将这些文件传递给 PHP 解释器,就可以在远程服务器上执行任意PHP脚本。 

解决方案: 

(1)检查服务器是否判断了上传文件类型及后缀。

(2) 定义上传文件类型白名单,即只允许白名单里面类型的文件上传。

(3) 文件上传目录禁止执行脚本解析,避免攻击者进行二次攻击。  Info漏洞 Info漏洞就是CGI把输入的参数原样输出到页面,攻击者通过修改输入参数而达到欺骗用户的目的。

Iframe安全隐患问题

解决方法:

1.使用安全的网站进行嵌入;

2.在iframe添加一个叫sandbox的属性,浏览器会对iframe内容进行严格的控制,详细了解可以看看相关的API接口文档。

本地存储数据问题:

第三方依赖安全隐患

HTTPS加密传输数据

 

 

 



 

 

 

六、计算机知识

七、小程序和app

1. 设计稿如何转换成标准的屏幕尺寸。

  设计稿一般为手机的长宽*2.

八、React

1. react生命周期。

组件将要挂载时触发的函数:componentWillMount

组件挂载完成时触发的函数:componentDidMount

是否要更新数据时触发的函数:shouldComponentUpdate

将要更新数据时触发的函数:componentWillUpdate

数据更新完成时触发的函数:componentDidUpdate

组件将要销毁时触发的函数:componentWillUnmount

父组件中改变了props传值时触发的函数:componentWillReceiveProps

2. hooksclass的区别,为什么要用hooks?(hooks解决了哪些问题)

  Hooks中有useStateuseReduceruseEffect可以在函数组件中执行副作用。useMemo手动添加依赖属性。useCallback便是用来处理这个问题,在依赖项不改变的情况下,函数不会重新定义。useRef操作DOMuseContext就是为了方便使用context(一般用于祖孙组件的数据通信)的。

解决的问题:在组件之间复用状态逻辑很难。

复杂组件变得难以理解。

难以理解的class

 

3.介绍一下redux

createStore这个函数,用来生成 Storereducer进行action的操作。

store.subscribe()设置监听函数。

store.getState()

store.dispatch()

store.subscribe()

用户发出action、调用reducerstore监听state的变化,使用setState重新渲染视图。

4.简述flux思想

 

9.redux执行的是浅比较还是深比较?

答:浅比较。

10.pureComponent执行的是浅比较还是深比较?

答:浅比较。

13.this.setState传对象和函数有什么区别,同步还是异步?

答:异步的。

传入对象的情况,如果有多个setState同时处理一个变量,会进行一个合并处理,最终可能只执行了一次;而传入函数的情况,函数的入参(prevState,props)每次都能拿到最新的state值。

setState在合成事件和生命周期函数中是异步的,在原生事件和setTimeOutsetState是同步的。

5.介绍一下diff算法React

策略一(tree diff):
Web UIDOM节点跨层级的移动操作特别少,可以忽略不计。

策略二(component diff):
拥有相同类的两个组件 生成相似的树形结构,
拥有不同类的两个组件 生成不同的树形结构。

策略三(element diff):
对于同一层级的一组子节点,通过唯一id区分。

6.什么是高阶组件?

高阶组件 其实就是一个函数而已,只不过参数是一个组件而已,返回了一个新的组件

复用组件的业务逻辑 react-redux  connect 其实就是一个高阶组件

HOC 是纯函数,没有副作用 ------纯函数:输入确定,输出就一定确定

7.react创建组件的方式有哪些?

函数组件/无状态组件、类组件

8.何为受控组件

没有自己的状态,数据由父组件提供,props获取值回调更改。

9. reactVUE的区别

相同点:虚拟DOM、组件化、props

不同点:模板与JSX、状态管理与对象属性、单向数据流与数据双向绑定

 

1.求100以内的质数

  for(var i=2 ; i<100 ; i++){
            var a = true;
        for(var j = 2; j < i; j++){
                //判断i能否被j整除
            if(i%j == 0){
            //能被整除则说明不是素数,修改布尔值为false
            a = false ;
            }
        }
        //打印素数
        if(a){
            console.log(i);
        }
        }   

  

 2.求字符串中出现字符最多de

   var str = "asddfssssaasswef";
        var obj = {};
        //遍历字符串,将出现的字符存入到数组中
        for (var i = 0; i < str.length; i++) {
            if (!obj[str.charAt(i)]) {
                obj[str.charAt(i)] = 1;
            } else {
                obj[str.charAt(i)]++;
            }
        }
        console.log(obj);
        var max = 0;
        var charmax;
        //遍历数组,找出出现最多的字母出现的次数
        for (var key in obj) {
            if (obj[key] > max) {
                max = obj[key];
                charmax = key;
            }
        }
        console.log("出现最多的字符是" + charmax + ",出现了" + max + "次");

  3   请将字符串open_my_door这种形式,转成OpenMyDoor的形式

var text ="open_my_door";

var newArr=text.split("_");

var str=new Array(3);

for( var i=0;i<newArr.length;i++){

    str[i]=newArr[i].substring(0,1).toUpperCase() + newArr[i].substring(1);            \

}

 

document.write(str.join(""));

  

 

posted @ 2020-10-26 14:47  yaqian96  阅读(64)  评论(0)    收藏  举报