原生js的面试题

1.JS的基本数据类型?引用数据类型?
基本数据类型(值类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、symbol。

引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function)。

特殊的对象:正则(RegExp)和日期(Date)。

特殊类型:Infinate 无穷、NAN 非数字。

2.es6新特性

1.变量声明:const和let
let表示声明变量,而const表示声明常量,两者都为块级作用域

区别:

  1. var声明的变量属于函数作用域,let和const声明的变量属于块级作用域;
  2. var存在变量提升现象(只在作用域中提升),而let和const没有;
  3. var变量可以重复声明,而在同一块级作用域,let变量不能重新声明,const变量不能修改。
  4. 暂时性死区:只要作用域内存在let、const,它们所声明的变量或常量就会自动“绑定”这个区域,不再受外部作用域的影响【这个暂时性死区说白了就是在函数作用域内部声明的变量将会与对应的函数作用域进行绑定(当然没有的话还是会向上查找),当函数内部存在重复声明或者变量提示时,就算外面的作用域已经声明了这个变量,它的运行还是认准的该函数作用域中的声明情况】
    在这里插入图片描述
    在这里插入图片描述
  5. window对象的属性和方法(全局作用域中): 全局作用域中,var声明的变量,通过function声明的函数,会自动变为window对象的变量,属性或方法,但const和let不会
    在这里插入图片描述

2.模板字符串
3.箭头函数(Arrow Functions)

箭头函数最直观的三个特点:
1.不需要 function 关键字来创建函数
2.省略 return 关键字
3.继承当前上下文的 this 关键字

4.函数的参数默认值

// ES6;
function printText(text = 'default') {
    console.log(text);
}

5.Spread / Rest 操作符(展开运算符)
Spread / Rest 操作符指的是 …,具体是 Spread 还是 Rest 需要看上下文语境。

当被用于迭代器中时,它是一个 Spread 操作符:

function foo(x,y,z) {
  console.log(x,y,z);
}
 
let arr = [1,2,3];
foo(...arr); // 1 2 3

当被用于函数传参时,是一个 Rest 操作符:当被用于函数传参时,是一个 Rest 操作符:

function foo(...args) {
  console.log(args);
}
foo( 1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]

6.二进制和八进制字面量
7.对象和数组解构

// 对象
const student = {
    name: 'Sam',
    age: 22,
    sex: '男'
}
// 数组
// const student = ['Sam', 22, '男'];

// ES5;
const name = student.name;
const age = student.age;
const sex = student.sex;
console.log(name + ' --- ' + age + ' --- ' + sex);

// ES6
const { name, age, sex } = student;
console.log(name + ' --- ' + age + ' --- ' + sex);

8.对象超类

ES6 允许在对象中使用 super 方法:

var parent = {
  foo() {
    console.log("Hello from the Parent");
  }
}
 
var child = {
  foo() {
    super.foo();
    console.log("Hello from the Child");
  }
}
 
Object.setPrototypeOf(child, parent);
child.foo(); // Hello from the Parent
             // Hello from the Child

9.for…of 和 for…in

let letters = ['a', 'b', 'c'];
letters.size = 3;
for (let letter of letters) {
  console.log(letter);
}
// 结果: a, b, c
for...in 用来遍历对象中的属性:

 let stus = ["Sam", "22", "男"];
 for (let stu in stus) {
   console.log(stus[stu]);
  }
// 结果: Sam, 22, 男

10.ES6中的类

ES6 中支持 class 语法,不过,ES6的class不是新的对象继承模型,它只是原型链的语法糖表现形式。

函数中使用 static 关键词定义构造函数的的方法和属性:

class Student {
  constructor() {
    console.log("I'm a student.");
  }
 
  study() {
    console.log('study!');
  }
 
  static read() {
    console.log("Reading Now.");
  }
}
 
console.log(typeof Student); // function
let stu = new Student(); // "I'm a student."
stu.study(); // "study!"
stu.read(); // "Reading Now."

类中的继承和超集:

class Phone {
  constructor() {
    console.log("I'm a phone.");
  }
}
 
class MI extends Phone {
  constructor() {
    super();
    console.log("I'm a phone designed by xiaomi");
  }
}
 
let mi8 = new MI();

extends 允许一个子类继承父类,需要注意的是,子类的constructor 函数中需要执行 super() 函数。
当然,你也可以在子类方法中调用父类的方法,如super.parentMethodName()。

有几点值得注意的是:

类的声明不会提升(hoisting),如果你要使用某个 Class,那你必须在使用之前定义它,否则会抛出一个 ReferenceError
的错误 在类中定义函数不需要使用 function 关键词

3.Null和undefined的区别

返回undefined类型的
1.变量声明且没有赋值
2.获取对象中不存在的属性
3.函数需要实参,但是调用时没有传值,形参是undefined
4.函数调用没有返回值或者return后没有数据,接受函数返回值的变量
返回null
1.对象不存在就是null
2.手动设置变量的值或某一个属性值为 null
3.JS 获取 DOM 元素,如果没有获取到指定的元素对象,返回 null
4.正则捕获时,如果没有捕获到,返回 null
5.Object.prototype.__proto__ 的值是 null
6.document 和 body 很多属性都是 null

相同点:
1.都是原始类型的值,且保存在栈中变量本地
2.进行条件判断时,两者都是false

区别:
1.null是js的关键字,表示空值;undefined不是js的关键字,它是一个全局变量
2.null是Object的一个特殊值,如果一个Object为null,表示这个对象不是有效对象,null是一个不存在的对象的占位符;undefined是Globel的一个属性
3.类型不一样:

 typeof(null) // object
 typeof(undefined) //undefined
 console.log(typeof(null) === 'object') //true
 console.log(typeof(undefied) === 'undefined')//true`在这里插入代码片`

4.转换的值不一样:

console.log(Number(undefined));//NaN
console.log(Number(11+ undefined));//NaN

console.log(Number(null));//0
console.log(Number(11+ null));//11

4.== 和 === 的区别

1.对于 string、number 等基础类型,== 和 === 的区别

1.不同类型间比较,== 之比较 "转化成同一类型后的值""值" 是否相等,=== 如果类型不同,其结果就是不等。
2.同类型比较,直接进行 "值" 比较,两者结果一样。

2.对于 Array,Object 等高级类型,== 和 === 的区别: 进行 “指针地址” 比较

3.基础类型与高级类型,== 和 ===的区别:

1.对于 ==,将高级转化为基础类型,进行 "值" 比较
2.因为类型不同,=== 结果为 false

5.Ajax的具体有哪些参数

1.url:
要求为String类型的参数,(默认为当前页地址)发送请求的地址。

2.type:
要求为String类型的参数,请求方式(post或get)默认为get。注意其他http请求方法,例如put和delete也可以使用,但仅部分浏览器支持。

3.timeout:
要求为Number类型的参数,设置请求超时时间(毫秒)。此设置将覆盖$.ajaxSetup()方法的全局设置。

4.async:
要求为Boolean类型的参数,默认设置为true,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为false。注意,同步请求将锁住浏览器,用户其他操作必须等待请求完成才可以执行。

5.cache:
要求为Boolean类型的参数,默认为true(当dataType为script时,默认为false),设置为false将不会从浏览器缓存中加载请求信息。

6.data:
要求为Object或String类型的参数,发送到服务器的数据。如果已经不是字符串,将自动转换为字符串格式。get请求中将附加在url后。防止这种自动转换,可以查看  processData选项。对象必须为key/value格式,例如{foo1:"bar1",foo2:"bar2"}转换为&foo1=bar1&foo2=bar2。如果是数组,JQuery将自动为不同值对应同一个名称。例如{foo:["bar1","bar2"]}转换为&foo=bar1&foo=bar2。

7.dataType:
要求为String类型的参数,预期服务器返回的数据类型。如果不指定,JQuery将自动根据http包mime信息返回responseXML或responseText,并作为回调函数参数传递。可用的类型如下:

xml:返回XML文档,可用JQuery处理。

html:返回纯文本HTML信息;包含的script标签会在插入DOM时执行。

script:返回纯文本JavaScript代码。不会自动缓存结果。除非设置了cache参数。注意在远程请求时(不在同一个域下),所有post请求都将转为get请求。

json:返回JSON数据。

jsonp:JSONP格式。使用SONP形式调用函数时,例如myurl?callback=?,JQuery将自动替换后一个“?”为正确的函数名,以执行回调函数。

text:返回纯文本字符串。

8.beforeSend:
要求为Function类型的参数,发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。XMLHttpRequest对象是惟一的参数。

function(XMLHttpRequest){

this;   //调用本次ajax请求时传递的options参数

}

9.complete:
要求为Function类型的参数,请求完成后调用的回调函数(请求成功或失败时均调用)。参数:XMLHttpRequest对象和一个描述成功请求类型的字符串。

function(XMLHttpRequest, textStatus){

this;    //调用本次ajax请求时传递的options参数

}

10.success:要求为Function类型的参数,请求成功后调用的回调函数,有两个参数。
(1)由服务器返回,并根据dataType参数进行处理后的数据。

(2)描述状态的字符串。

function(data, textStatus){
	//data可能是xmlDoc、jsonObj、html、text等等
	this;  //调用本次ajax请求时传递的options参数
}

11.error:
要求为Function类型的参数,请求失败时被调用的函数。该函数有3个参数,即XMLHttpRequest对象、错误信息、捕获的错误对象(可选)。ajax事件函数如下:

function(XMLHttpRequest, textStatus, errorThrown){
	//通常情况下textStatus和errorThrown只有其中一个包含信息
	this;   //调用本次ajax请求时传递的options参数
}

12.contentType:
要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。

13.dataFilter:
要求为Function类型的参数,给Ajax返回的原始数据进行预处理的函数。提供data和type两个参数。data是Ajax返回的原始数据,type是调用jQuery.ajax时提供的dataType参数。函数返回的值将由jQuery进一步处理。
function(data, type){
	//返回处理后的数据
	return data;
}

14.global:
要求为Boolean类型的参数,默认为true。表示是否触发全局ajax事件。设置为false将不会触发全局ajax事件,ajaxStart或ajaxStop可用于控制各种ajax事件。

15.ifModified:
要求为Boolean类型的参数,默认为false。仅在服务器数据改变时获取新数据。服务器数据改变判断的依据是Last-Modified头信息。默认值是false,即忽略头信息。

16.jsonp:
要求为String类型的参数,在一个jsonp请求中重写回调函数的名字。该值用来替代在"callback=?"这种GETPOST请求中URL参数里的"callback"部分,例如{jsonp:'onJsonPLoad'}会导致将"onJsonPLoad=?"传给服务器。

17.username:
要求为String类型的参数,用于响应HTTP访问认证请求的用户名。

18.password:
要求为String类型的参数,用于响应HTTP访问认证请求的密码。

19.processData:
要求为Boolean类型的参数,默认为true。默认情况下,发送的数据将被转换为对象(从技术角度来讲并非字符串)以配合默认内容类型"application/x-www-form-urlencoded"。如果要发送DOM树信息或者其他不希望转换的信息,请设置为false20.scriptCharset:
要求为String类型的参数,只有当请求时dataType为"jsonp"或者"script",并且type是GET时才会用于强制修改字符集(charset)。通常在本地和远程的内容编码不同时使用。

6.Get和Post的区别

1.GET的数据在URl中是可见的。POST请求不现实在URL;
2.GET对长度是有限制的,POST长度是无限的;
3.GET请求的数据可以收藏为书签,POST请求到的数据不可以收藏为书签;
4.GET请求后,安后退按钮、刷新按钮无影响,POST数据会被重新提交;
5.GET编码:application/x-www.form-url,POST的编码类型:有很多种.encodeapplication/x-www/from-urlencoded(加密了编码的),multipart/form-data;
6.GET历史参数会被保留在浏览器里,post不会保存在浏览器中的;
7.GET只允许ASCll,post没有编码限制,允许发二进制;
8.GETPOST相比,GET安全性较差,因为所发的数据是URL的一部分.

7.项目是否前后端分离?前后端分离的意义?

优点:
1.提高开发效率
前后端各负其责, 前端和后端都做自己擅长的事情,不互相依赖,开发效率更快,而且分工比较均衡,会大大提高开发效率
2.用户访问速度快,提升页面性能,优化用户体验
没有页面之间的跳转,资源都在同一个页面里面,无刷线加载数据,页面片段间的切换快,使用户体验上升了一大截;前后端不分离,稍不留神会触发浏览器的重排和重绘,加载速度慢,降低用户的体验
3.增强代码可维护性,降低维护成本,改善代码的质量
前后端不分离,代码较为繁杂,维护起来难度大,成本高
4.减轻了后端服务器的请求压力
公共资源只需要加载一次,减少了HTTP请求数
5.同一套后端程序代码,不用修改就可以用于Web界面、手机、平板等多种客户端

缺点:
1.首屏渲染的时间长
将多个页面的资源打包糅合到一个页面,这个页面一开始需要加载的东西会非常多,而网速是一定的,所以会导致首屏渲染时间很长,首屏渲染后,就是无刷新更新,用户体验相对较好
2.不利于搜索引擎的优化(SEO)
现有的搜索引擎都是通过爬虫工具来爬取各个网站的信息,这些爬虫工具一般只能爬取页面上(HTML)的内容,而前后端分离,前端的数据基本上都是存放在行为逻辑(JavaScript)文件中,爬虫工具无法爬取,无法分析出你网站到底有什么内容,无法与用户输入的关键词做关联,最终排名就低
3.不能使用浏览器里面的前进后退功能
4.一些版本较低的浏览器对其支持度不足

总结:
是否要分离,由具体业务来决定
若需要搜索引擎带来流量,则不分离
若需要App和后端交互,必须分离
若需要用户登录且不能由搜索引擎抓取,可以选择分离
若需要网站前端效果绚丽,跨设备兼容要求高,可以选择分离
若网站尚处于原始开发模式,数据逻辑与表现逻辑混杂不清,可以选择分离

8.http和https的区别;两者的优缺点

1.https的端口是443,而http的端口是80,且两者的连接方式不同;
2.http传输是明文的,而https是用ssl进行加密的,https的安全性更高;
3.https是需要申请证书的,而http不需要。

9.http的请求报文的组成

HTTP
超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议,是客户端浏览器或其他程序“请求”与 Web 服务器响应之间的应用层通信协议。HTTP 是一种请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求;服务器接到请求后,给予相应的响应信息。

HTTPS主要是由HTTP+SSL构建的可进行加密传输、身份认证的一种安全通信通道。

HTTP请求报文有四部分组成:请求行,请求头,空行,请求数据

1.请求行

请求行由下面三部分组成

请求方法:GETPOST
请求网址(URL)
协议版本:HTTP1.1

GET /index.jsp HTTP/1.1

2.请求头

内容: { ‘头部字段名’ : ‘值’ } * N (可以有多个)
例如: {‘Referer’ : ‘https://ts2.cn.mm.bing.net’,USER-AGENT : ‘python-requests/2.22.0}
Accept-Language: zh-cn
Connection: Keep-Alive
Host: 192.168.0.106
Content-Length: 37

3.空行
它的作用是通过一个空行,告诉服务器请求头部到此为止。

4.请求数据
请求包体,通常只有POST请求才有

10.http的状态码?100,200,400,404,500,505等含义

1.该类型状态码表示接收到请求并且继续处理

100:客户端必须继续发出请求。
101:客户端要求服务器根据请求转换HTTP协议版本。

2.该类型状态码表示动作被成功接收、理解和接受。

200,表明该请求被成功地完成,所请求的资源发送到客户端。
201,提示知道新文件的URL202,接受并处理,但处理未完成。
203,返回信息不确定或不完整。
204,收到请求,但返回信息为空.
205,服务器完成了请求,用户必须复位当前已经浏览过的文件。
206,服务器已经完成了部分用户的GET请求。

3.该类型状态码表示为了完成指定的动作,必须接受进一步处理。

300,请求的资源可在多处获得。
301,本网页被永久性转移到另一个URL302,请求的网页被重定向到新的地址。
303,建议用户访问其他URL或访问方式。
304,自从上次请求后,请求的网页未修改过。
305,请求的资源必须从服务器指定的地址获得。
306,前一版本HTTP中使用的代码,现已不再使用。
307,声明请求的资源临时性删除。

4.该类型状态码表示请求包含错误语法或不能正确执行。

400,客户端请求有语法错误。
401,请求未经授权。
402,保留有效ChargeTo头响应。
403,禁止访问,服务器收到请求,但拒绝提供服务。
404,可连接服务器,但服务器无法取得所请求的网页,请求资源不存在。
405,用户在Request-Line字段定义的方法不被允许。
406,根据用户发送的Accept,请求资源不可访问。
407,类似401,用户必须首先在代理服务器上取得授权。
408,客户端没有在用户指定的时间内完成请求。
409,对当前资源状态,请求不能完成。
410,服务器上不再有此资源。
411,服务器拒绝用户定义的Content-Length属性请求。
412,一个或多个请求头字段在当前请求中错误。
413,请求的资源大于服务器允许的大小。
414,请求的资源URL长于服务器允许的长度。
415,请求资源不支持请求项目格式。
416,请求中包含Range请求头字段,在当前请求资源范围内没有range指示值。
417,服务器不满足请求Expect头字段指定的期望值。

5.该类型状态码表示服务器或网关错误。

500,服务器错误。
501,服务器不支持请求的功能。
502,网关错误。
503,无法获得服务。
504,网关超时。
505,不支持的http版本。

11.Symbol的含义和使用

Symbol是ES6中新增的一种数据类型, 被划分到了基本数据类型中

1.Symbol的作用
用来表示一个独一无二的值

2.格式
let xxx=Symbol(‘标识字符串’);

3.为什么需要Symbol?
为了避免第三方框架的同名属性被覆盖

在企业开发中如果需要对一些第三方的插件、框架进行自定义的时候
可能会因为添加了同名的属性或者方法, 将框架中原有的属性或者方法覆盖掉
为了避免这种情况的发生, 框架的作者或者我们就可以使用Symbol作为属性或者方法的名称

4.如何区分Symbol?
在通过Symbol生成独一无二的值时可以设置一个标记
这个标记仅仅用于区分, 没有其它任何含义

12.防抖和节流的含义

防抖是指当一个事件触发的时候, 为防止频繁触发事件, 设置定时器,以达到一种 频繁触发期间不处理, 只有当最后一次连续触发结束以后才处理。
常用在:搜索和window触发resize的时候

节流是指当一个事件触发的时候,为防止事件的连续频繁触发,设置定时器,达到一种一段事件内只触发一次的效果,在当前事件内不会再次触发,当前事件结束以后,再次触发才有效。
常用在:鼠标不断点击触发和监听滚动事件

13.线程和进程是什么?

进程:cpu分配资源的最小单位(是能拥有资源和独立运行的最小单位)
线程:是cpu最小的调度单位(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程)

14.对内存泄漏的了解
1.理解
定义:程序中已在堆中分配的内存,因为某种原因未释放或者无法释放的问题
简单理解: 无用的内存还在占用,得不到释放和归还,比较严重的时候,无用的内存还会增加,从而导致整个系统卡顿,甚至崩溃。

2.生命周期

1.分配期
  分配所需要的内存,在js中,是自动分配的
2.使用期
  使用分配的内存,就是读写变量或者对象的属性值
3.释放期
  不需要时将该内存释放,js会自动释放(除了闭包和一些bug以外)
  内存泄漏就是出现在这个时期,内存没有被释放导致的

3.可能出现内存泄漏的原因

1.意外的全局变量
2.DOM元素清空时,还存在引用
3.闭包
4.遗忘的定时器

如何优化内存泄漏?

全局变量先声明在使用
避免过多使用闭包。
注意清除定时器和事件监听器。

15.js中数组合并的方法

1.arr1.concat(arr2, ······)
2.[…arr1, …arr2,······]
3.push(…arr)

16.合并对象的方法

Object.assign()方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target),实行的是浅拷贝

17.什么是作用域,什么是作用域链?

规定变量和函数的可使用范围称为作用域
查找变量或者函数时,需要从局部作用域到全局作用域依次查找,这些作用域的集合称作用域链。

18.JS如何实现异步编程(5种)

1.回调函数(callback)
优点:解决了同步的问题(只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。)
缺点:回调地狱,每个任务只能指定一个回调函数,不能 return.

2.事件监听。这种思路是说异步任务的执行不取决于代码的顺序,而取决于某个事件是否发生。比如一个我们注册一个按钮的点击事件或者注册一个自定义事件,然后通过点击或者trigger的方式触发这个事件。

3.Promise

4.Generator

5.生成器 async/await,ES7提供的一种解决方案。

19.js中的堆内存与栈内存

在js引擎中对变量的存储主要有两种位置,堆内存和栈内存。

栈内存主要用于存储各种基本类型的变量,包括Boolean、Number、String、Undefined、Null,**以及对象变量的指针,这时候栈内存给人的感觉就像一个线性排列的空间,每个小单元大小基本相等。
而堆内存主要负责像对象Object这种变量类型的存储

20.如何去判断js数据类型?

typeof只能判断基本数据类型,对于引用数据类型,- -律返回object,在js中,数组是一种特殊的对象类型, 因此typeof-个数组,返回的是object.

通过instanceof来判断,它不能检测基本数据类型,它是用来判断个实例是否属于某种类型, 使用它的方式可以用Ainstanceof B,如果A是B的实例,则返回true,否则返回flase。

用constructor来判断,除了undefined和null之外,其它类型都可以通过constructor来判断,但是如果声明了一个构造函数,并且把它的原型指向改变了,这种情况下,constructor也不能准确的判断。

通过0bject . prototype . toString,判断一个对象 只属于某种内置类型,但是不能准确的判断一个实例是否属于某种类型。

21.怎么允许跨域(跨域解决办法)

1.JSONP
在页面上,js脚本,css样式文件,图片这三种资源是可以与页面本身不同源的。jsonp就利用了script标签进行跨域取得数据。
JSONP允许用户传递一个callback参数给服务器端,然后服务器端返回数据时会将这个callback参数作为函数名来包裹住JSON数据。这样客户端就可以随意定制自己的函数来自动处理返回的数据了。

JSONP只能解决get请求,不能解决post请求。

使用ajax实现跨域:

  $.ajax({
       url:'http://localhost:80/?callback=callback',
       method:'get',
       dataType:'jsonp', //=> 执行jsonp请求
       success:(res) => {
           console.log(res);
       }
   })

   function callback(data){
       console.log(data);
   }

2.CORS跨域资源共享:
浏览器会自动进行CORS通信,实现CORS通信的关键是后端。
服务端设置Access-Control-Allow-Origin就可以开启CORS。该属性表示哪些域名跨域访问资源。
主要设置以下几个属性:
Access-Control-Allow-Origin//允许跨域的域名
Access-Control-Allow-Headers//允许的header类型
Access-Control-Allow-Methods//跨域允许的请求方式

3.Nginx反向代理
通过nginx配置一个代理服务器将客户机请求转发给内部网络上的目标服务器;并将服务器上返回的结果返回给客户端。

4.webpack (在vue.config.js文件中)中 配置webpack-dev-server

devServer: {
   proxy: {
     '/api': {
       target: "http://39.98.123.211",
       changeOrigin: true,  //是否跨域
     },
   },
 },

22.js有哪些内置对象?

数据封装类对象:Object、Array、Boolean、Number 和 String
其他对象:Function、Arguments、Math、Date、RegExp、Error…

23.tcp/udp的协议,两者的区别

UDP的特点

无连接:知道对端的IP和端口号就直接进行传输,不需要建立连接
不可靠:没有确认机制,没有重传机制
面向数据报:应用层交给UDP多长的报文, UDP原样发送,既不会拆分, 也不会合并,所以不能够灵活的控制读写数据的次数和数量
理解UDP的“不可靠”

UDP可以保证传输的数据不被修改

报文可能会丢失(原因:1.传输介质本身可能丢包;2.传输介质可能导致数据错误,进而被UDP丢弃.)
报文顺序可能会错乱(原因:网络层不同的寻路可能导致到达顺序不固定)

TCP(Transmission Control Protocol)全称为 “传输控制协议”。顾名思义,TCP要对数据的传输进行一个详细的控制。

TCP协议段格式:

1./目的端口号:表示数据是从哪个进程来,到哪个进程去
2.32位序号:TCP将每个字节的数据都进行了编号. 即为序列号
3.32位确认序号:每一个ACK都带有对应的确认序列号, 意思是告诉发送者, 我已经收到了哪些数据; 下一次你从哪里开始发

4.6位标志位:
	URG: 紧急指针是否有效
	ACK: 确认号是否有效
	PSH: 提示接收端应用程序立刻从TCP缓冲区把数据读走
	RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段
	SYN: 请求建立连接; 我们把携带SYN标识的称为同步报文段
	FIN: 通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段
5.16位窗口大小:TCP 要做流量控制,需要通信双方各声明一个窗口,标识自己当前的处理能力

1.确认应答(ACK)机制

TCP通过确认应答机制保证发送的数据对方一定收到了,通过对数据编号,可以知道应答的是哪份数据。

2.超时重传机制

主机A发送数据给B之后, 可能因为网络拥堵等原因, 数据无法到达主机B;
如果主机A在一个特定时间间隔内没有收到B发来的确认应答, 就会进行重发

3.连接管理机制

一条连接的生命周期:建立连接极端——>连接可用阶段——>断开连接阶段

4.TCP三次握手

TCP建立连接过程中,一共需要三次数据交互。
第一次握手:
(1)服务器[CLOSEDLISTEN]:服务器创建完TCB后便进入LISTEN状态,准备接收客户端A发来的连接请求;
(2)客户端[CLOSEDSYN_SENT]:客户端A向服务器B发送连接请求报文段。该报文段的头部中SYN=1ACK=0,seq=x。请求发送后,客户端A便进入SYN-SENT状态;
第二次握手:
(3)服务器[LISTENSYN_RCVD]:服务器B收到连接请求报文段后,如果同意连接,则会发送一个应答:SYN=1ACK=1,seq=y,ack=x+1。该应答发送完成后便进入SYN-RCVD状态;
第三次握手:
(4)客户端[SYN_SENTESTABLISHED]:当客户端A收到连接同意的应答后,还要向服务器B发送一个确认报文段,该报文段的头部为:ACK=1,seq=x+1,ack=y+1。表示:服务器B发来的连接同意应答已经成功收到。客户端A发完这个报文段后便进入STABLISHED状态。
(5)服务器[SYN_RCVDESTABLISHED]:服务器B收到这个应答后也进入ESTABLISHED状态,此时连接的建立完成!

5.TCP四次挥手

TCP连接是双向的,因此在四次挥手中,前两次挥手用于断开一个方向的连接,后两次挥手用于断开另一方向的连接。
第一次挥手:
(1)客户端[ESTABLISHEDFIN_WAIT_1]:若客户端A认为数据发送完成,则它需要向服务端B发送连接释放请求。该请求只有报文头,头中携带的主要参数为:FIN=1,seq=u。此时,客户端A将进入FIN-WAIT-1状态;
第二次挥手:
(2)服务器[ESTABLISHEDCLOSE_WAIT]:服务器B收到连接释放请求后,会通知相应的应用程序,告诉它客户端A向服务器B这个方向的连接已经释放。此时服务器B进入CLOSE-WAIT状态,并向客户端A发送连接释放的应答,其报文头包含:ACK=1,seq=v,ack=u+1;
(3)客户端[FIN_WAIT_1FIN_WAIT_2]:客户端A收到该应答,进入FIN-WAIT-2状态,等待服务器B发送连接释放请求。
第三次挥手:
(4)服务器[CLOSE_WAITLAST_ACK]:当服务器B向客户端A发完所有数据后,向客户端A发送连接释放请求,请求头:FIN=1ACK=1,seq=w,ack=u+1。服务器B便进入LAST-ACK状态;
第四次挥手:
(5)客户端[FIN_WAIT_2TIME_WAITCLOSED]:客户端A收到释放请求后,向服务器B发送确认应答,请求头:ACK=1,seq=u+1,ack=w+1。此时客户端A进入TIME-WAIT状态。该状态会持续2MSL时间,若该时间段内没有服务器B的重发请求的话,就进入CLOSED状态,撤销TCB。
(6)服务器[LAST_ACKCLOSED]:当服务器B收到确认应答后,也便进入CLOSED状态,撤销TCB

TCP和UDP的区别

TCP优点:可靠
UDP优点:实时性更好(速度快),UDP可以广播、多播。例:音视频直播等
UDP没有发送缓冲区,有接收缓冲区;
TCP有发送缓冲区,也有接收缓冲区;
TCP是面向有连接型,UDP是面向无连接型;
TCP是一对一传输,UDP支持一对一、一对多、多对一和多对多的交互通信;
TCP是面向字节流的,UDP是面向数据报的;
TCP支持传输可靠性的多种措施,包括保证包的传输顺序、重发机制、流量控制和拥塞控制;UDP仅提供最基本的数据传输能力;
TCP 保证数据正确性,UDP 可能丢,TCP 保证数据顺序,UDP 不保证。

24.解释一下什么是闭包

闭包就是能够读取其他函数内部变量的函数

闭包需要满足三个条件:

访问所在作用域;
函数嵌套;
在所在作用域外被调用 。

优点: 可以重复使用变量,并且不会造成变量污染 。

缺点: 会引起内存泄漏

使用闭包的注意点:

1.由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2.闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象
(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

25.解释一下原型和原型链

原型就是一个为对象实例定义了一些公共属性和公共方法的对象模板。

原型链

对象之间的继承关系通过构造函数的prototype指向父类对象,直到指向Object对象为止形成的指向链条。

通俗讲: 原型链是原型对象创建过程的历史记录。 

注:在javascript中,所有的对象都拥有一个__proto__属性指向该对象的原型(prototype)

26.for 循环与 forEach 的区别

1.for循环可以使用break跳出循环,但forEach不能。
2.for循环可以控制循环起点(i初始化的数字决定循环的起点),forEach只能默认从索引0开始。
3.for循环过程中支持修改索引(修改 i),但forEach做不到(底层控制index自增,无法左右它)。

27.url 的组成

http:/https:    协议
www.baidu.com  域名
:8080  端口
/sf/vsearch  路径
?wd=百度热搜   查询(可有可无)  

28.什么是 Promise

Promise 是异步编程的一种解决方案:从语法上讲,promise是一个对象,从它可以获取异步操作的消息;
从本意上讲,它是承诺,承诺它过一段时间会给你一个结果。

promise有三种状态: pending(等待态),fulfilled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行

promise是用来解决两个问题的:
1.回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象
2.promise可以支持多个并发的请求,获取并发请求中的数据

这个promise可以解决异步的问题,本身不能说promise是异步的

Promise 的使用场景
1.获取文件信息。
2.配合AJAX获取信息
3.解决回调地狱,实现串行任务队列。
4.node中进行本地操作的异步过程。

29.cookie, localStorage,sessionStorage 的区别

cookie

1.存储方式
 存储用户信息,获取数据需要与服务器建立连接。
 以路径存储,上层路径不能访问下层的路径cookie,下层的路径cookie可以访问上层的路径cookie 
 作用与特性 

2.可存储的数据有限,且依赖于服务器,无需请求服务器的数据尽量不要存放在cookie 中,以免影响页面性能。

3.可设置过期时间。

4.存储数量及大小 将cookie控制在4095B以内,超出的数据会被忽略。
IE6或更低版本 最多存20个cookie; 
IE7及以上
版本 多可以有50个;
Firefox多 50个;
chrome和Safari没有做硬性限制。

cookie最大特征就是可以在页面与服务器间互相传递,当发送或者接受数据时自动传递
localStorage

1.存储客户端信息,无需请求服务器。

2.数据永久保存,除非用户手动清理客户端缓存。

3.开发者可自行封装一个方法,设置失效时间。	5M左右,各浏览器的存储空间有差异。

4.任何地方都可以存都可以取
sessionStorage	

1.存储客户端信息,无需请求服务器。

2.数据保存在当前会话,刷新页面数据不会被清除,结束会话(关闭浏览器、关闭页面、跳转页面)数据失效。	

3.5M左右,各浏览器的存储空间有差异。

4.同页面不同窗口中数据不会共享

30.输入 url 到打开页面 都做了什么事情

输入URL
访问hosts解析,如果没有解析访问DNS解析
TCP握手
HTTP请求
HTTP响应返回数据
浏览器解析并渲染页面

31.如何实现继承 ?

对于 JavaScript 来说,继承有两个要点:
1.复用父构造函数中的代码
2.复用父原型中的代码第一种实现复用父构造函数中的代码,我们可以考虑调用父构造函数并将 this 绑定到子构造函数。

第一种方法:复用父原型中的代码,我们只需改变原型链即可。将子构造函数的原型对象的 proto 属性指向父构造函数的原型对象。

第二种实现
使用 new 操作符来替代直接使用 proto 属性来改变原型链。

第三种实现
使用一个空构造函数来作为中介函数,这样就不会将构造函数中的属性混到 prototype 中

第四种实现
es6类的继承extends。

32.普通函数与箭头函数的区别

1.箭头函数没有prototype(原型),箭头函数没有自己的this,继承的是外层代码块的this。
2.不可以当做构造函数,也就是说不可以使用new命令,否则会报错的。
3.不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
4.不可以使用yield命令,因此箭头函数不能用作 Generator(生成器) 函数。
5.因为没有this,所以不能使用call、bind、apply来改变this的指向

33.设计模式有哪些, 分别说一说

共23种设计模式,介绍其中6种应用较为广泛的模式。

1.发布订阅模式:
这种设计模式可以大大降低程序模块之间的耦合度,便于更加灵活的扩展和维护。

2.中介者模式 :
观察者模式通过维护一堆列表来管理对象间的多对多关系,中介者模式通过统一接口来维护一对多关系,且通信者之间不需要知道彼此之间的关系,只需要约定好API即可。

3.代理模式 :
为其他对象提供一种代理以控制对这个对象的访问。
代理模式使得代理对象控制具体对象的引用。代理几乎可以是任何对象:文件,资源,内存中的对象,或者是一些难以复制的东西。

4.单例模式 :
保证一个类只有一个实例,并提供一个访问它的全局访问点(调用一个类,任何时候返回的都是同一个实例)。

5.工厂模式 :
工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一
个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型

6.装饰者模式 : 装饰者(decorator)模式能够在不改变对象自身的基础上,在程序运行期间给对像动态的添加职责(方法或属性)。与继承相比,装饰者是一种更轻便灵活的做法。

34.Promsie 和 async/await 的区别和使用

1.函数前面多了一个async关键字。await关键字只能用在async定义的函数内。async函数会隐式地返回一个promise,该promise的reosolve值就是函数return的值。
2.第1点暗示我们不能在 外层代码中使用await,因为不在async函数内。使用:

	1.async和await是配对使用的,await存在于async的内部。否则会报错 。
	2.await表示在这里等待一个promise返回,再接下来执行。
	3.await后面跟着的应该是一个promise对象,(也可以不是,如果不是接下来也没什么意义了…)

35.垃圾回收机制

垃圾回收是动态存储管理技术,会自动地释放“垃圾‘’(不再被程序引用的对象),按照特定的垃圾收集算法来实现资源自动回收的功能。

回收的两种机制
1.标记清除(make-and-sweep)
2.引用计数 垃圾回收器会按照固定的时间间隔周期性的执行。

36.new 一个对象的过程

1.开辟一个堆内存,创建一个空对象
2.执行构造函数,对这个空对象进行构造
3.给这个空对象添加__proto__属性

37.箭头函数为什么不能用 new

因为箭头函数没有prototype也没有自己的this指向并且不可以使用arguments。

38.数组去重

第一种:for

for(var i=0;i<arr.length;i++){ 
	for(var j=i+1;j<arr.length;){ 
		if(arr[i]===arr[j]) arr.splice(j,1); 
		else j++; // 核心 
	} 
} 

第二种:indexOf

var arr1=[]; 
for(var i=0;i<arr.length;i++){ 
	if(arr1.indexOf(arr[i])<0) arr1.push(arr[i]) 
} 

第三种:includes

var arr1=[]; 
for(var i=0;i<arr.length;i++){ 
	if(!arr1.includes(arr[i])) arr1.push(arr[i])
}

第四种:new Set

arr=[1,2,3,1,2,3,1,2,3] 
new Set(arr); 

39.判断对象为空

1.使用JSON.stringify()将对象转换为json字符串; 
JSON.stringify(obj) === '{}' 

2.使用for...in循环遍历对象除Symbol以外的所有可枚举属性,当对象有属性存在返回false, 否则返回 
trueconst obj = {} 
function isObjectEmpty(obj){ 
	for(var key in obj){ 
		return false 
	}
	return true 
}
console.log(isObjectEmpty(obj)) 

3.Object.keys()ES5 新增的一个对象方法,该方法返回一个数组,包含指定对象自有的可枚举属性(不 
含继承的和Symbol属性)。用此方法只需要判断返回的数组长度是否为零,如果为零的话就是空对象。

4.Object.getOwnPropertyNames() 方法会返回该对象所有可枚举和不可枚举属性的属性名(不含Symbol 
属性)组成的数组。然后再通过判断返回的数组长度是否为零,如果为零的话就是空对象。 
Object.getOwnPropertyNames(obj).length === 0 

40.如何实现数组的复制

1.for循环逐一复制;
  var arr1=[];
  for(var i=0;i<arr.length;i++){
    if(i in arr) arr1[i]=arr[i]
  }
  
2.…方式
  var arr1=[...arr];
  
3.slice方法
  var arr1=arr.slice();

4.concat方法
  var arr1=arr.concat();

5.map方法
  var arr1=arr.map(item=>item);

6.educe
  var arr1=arr.reduce((v,t)=>v.push(t),[])

41.Promsie.all() 使用过吗, 它是怎么使用的

promise.all()用于一个异步操作需要在几个异步操作完成后再进行时使用。

promise.all()接受一个promise对象组成的数组参数,返回promise对象。

当数组中所有promise都完成了,就执行当前promise对象的then方法,如果数组中有一个promise执行失败了,就执行当前promise对象的catch方法。

42.for in 和 for of 循环的区别

`for in` 用于遍历对象的键(`key`)`for in`会遍历所有自身的和原型链上的可枚举属性。
如果是数组,for in会将数组的索引(index)当做对象的key来遍历,其他的object也是一样的。

`for of``es6`引入的语法,用于遍历 所有迭代器iterator,
其中包括`HTMLCollection`,`NodeList`,`Array``Map``Set``String``TypedArray``arguments`等对象的值(`item`)

43.async/await 怎么抛出错误异常

如果可能出错的代码比较少的时候可以使用try/catch结构来了处理,如果可能出错的代码比较多的时候,可以利用async函数返回一个promise对象的原理来处理,给async修饰的函数调用后返回的promise对象,调用catch方法来处理异常。

44.函数式编程和命令式编程的区别

命令式编程(过程式编程) :
专注于”如何去做”,这样不管”做什么”,都会按照你的命令去做。
解决某一问题的具体算法实现。

函数式编程:把运算过程尽量写成一系列嵌套的函数调用。
函数式编程强调没有”副作用”,意味着函数要保持独立,所有功能就是返回一个新的值,没有其他行为,尤其是不得修改外部变量的值。
所谓”副作用”,指的是函数内部与外部交互(最典型的情况,就是修改全局变量的值),产生运算以外的其他结果。

45.什么是事件流以及事件流的传播机制

事件触发后,从开始找目标元素,然后执行目标元素的事件,再到离开目标元素的整个过程称之为事件流。

W3C标准浏览器事件流的传播分为3个阶段:捕获阶段、目标阶段、冒泡阶段

捕获阶段指找目标元素的过程,这个找的过程,是从最大的document对象到html,再到body,。。。直到目标元素。

找到目标元素后,调用执行他绑定事件时对应的处理函数,这个过程被称之为目标阶段。

当目标元素的事件执行结束后,再从目标元素,到他的父元素。。。body、html再到document的过程,是冒泡阶段。

46.什么是懒加载和预加载 ?
懒加载:懒加载也叫延迟加载,延迟加载网络资源或符合某些条件时才加载资源。常见的就是图片延时加载。
懒加载的意义:懒加载的主要目的是作为服务器前端的优化,减少请求数或延迟请求数。

懒惰实现方式:
1.第一种是纯粹的延迟加载,使用setTimeOut或setInterval进行加载延迟.
2.第二种是条件加载,符合某些条件,或触发了某些事件才开始异步下载。
3.第三种是可视区加载,即仅加载用户可以看到的区域,这个主要由监控滚动条来实现,一般会在距用户看到某图片前一定距离遍开始加载,这样能保证用户拉下时正好能看到图片。

预加载:提前加载图片,当用户需要查看时可直接从本地缓存中渲染。

两者的行为是相反的,一个是提前加载,一个是迟缓甚至不加载。
懒加载对服务器前端有一定的缓解压力作用,预加载则会增加服务器前端压力。预加载应用如广告弹窗等。

47.token 一般存放在哪里 ? 为什么不存放在 cookie 内

token一般放在本地存储中。token的存在本身只关心请求的安全性,而不关心token本身的安全,因为token是服务器端生成的,可以理解为一种加密技术。但如果存在cookie内的话,浏览器的请求默认会自动在请求头中携带cookie,所以容易受到csrf攻击。

48.less 和 sass 的区别

编译环境不一样,sass是服务器端处理的,可以用Ruby、node-sass来编译;less需要引入less.js来处理输出,也可以使用工具在服务器端处理成css,也有在线编译的。

变量定义符不一样,less用的是@,而sass用$。

sass支持分支语句,less不支持。

49.浏览器的同源策略机制

同源策略,又称SOP,全称Same Origin Policy,是浏览器最基本的安全功能。站在浏览器的较短看网页,如果网络上的接口可以不受限制、无需授权随意被人调用,那将是一个非常严重的混乱场景。浏览器为了安全有序,内部实现了同源策略。

同源策略,指的是浏览器限制当前网页只能访问同源的接口资源。

所谓同源,指当前页面和请求的接口,两方必须是同协议、且同域名、且同端口。只要有一个不相同,则会受到浏览器额约束,不允许请求。

但当一个项目变的很大的时候,将所有内容放在一个网站或一个服务器中会让网站变的臃肿且性能低下,所以,在一些场景中,我们需要跨过同源策略,请求到不同源的接口资源,这种场景叫跨域。

跨域大致有3种方案:

1.jsonp

这种方式是利用浏览器不限制某些标签发送跨域请求,例如link、img、iframe、script。通常请求请求回来的资源要在js中进行处理,所以jsonp跨域是利用script标签进行发送,且这种请求方式只能是get请求。

2.cors

这种方式是让接口资源方面进行授权,授权允许访问。在接口资源处添加响应头即可通过浏览器的同源策略,响应头具体的键值对如下:

{Access-Control-Allow-Origin: '*'}

3.proxy

这种方式属于找外援的一种方式,浏览器只能限制当前正在打开的web页面发送请求,但无法限制服务器端请求接口资源。所以我们可以将请求发送到自己服务器,然后自己服务器去请求目标接口资源,最后自己服务器将接口资源返回给当前页面,类似于找外援代替自己请求目标接口资源。

这种方式通常要对服务器进行代理配置,需要对apache服务器、nginx服务器、nodejs服务器进行配置

50.浏览器的缓存有哪些 ? 什么时候使用强制缓存 ? 什么时候使用协商缓存 ?

当我们访问同一个页面时,请求资源、数据都是需要一定的耗时,如果可以将一些资源缓存下来,那么从第二次访问开始,就可以减少加载时间,提高用户体验,也能减轻服务器的压力。

浏览器缓存分为强缓存和协商缓存,当存在缓存时,客户端第一次向服务器请求数据时,客户端会缓存到内存或者硬盘当中,当第二次获取相同的资源,强缓存和协商缓存的应对方式有所不同。

强缓存:当客户端第二次向服务器请求相同的资源时,不会向服务器发送请求,而是直接从内存/硬盘中间读取。缓存由服务器的响应头里 cache-control 和 expires 两个字段决定

协商缓存:当客户端第二次向服务器请求相同的资源时,先向服务器发送请求"询问"该请求的文件缓存在ben’d与服务器相比是否更改,如果更改,则更新文件,如果没有就从内存/硬盘中读取。协商缓存由 last-modified 和 etag两个字段决定

51.数组方法 forEach 和 map 的区别 ?

forEach和map都是循环遍历数组中的每一项。forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前项的索引index,原始数组input。匿名函数中的this都是指Window。只能遍历数组。

他们的区别是:forEach没有返回值,但map中要有返回值,返回处理后的所有新元素组成的数组。

52. 0.1 + 0.2 为什么不等于 0.3, 在项目中遇到要怎么处理 ?

计算机内部存储数据使用2进制存储,两个数字进行的数学运算,首先是将这两个数字以2进制形式,存储在计算机内部,然后在计算机内部使用两个2进制数字进行计算,最后将计算结果的2进制数字转为10进制展示出来。

由于10进制的小数在转2进制的时候,规则是小数部分乘以2,判断是否得到一个整数,如果得到整数,转换完成;如果没有得到整数,则继续乘以2判断。所以,0.1和0.2在转换2进制的时候,其实是一个无限死循环,也就是一直乘以2没有得到整数的时候,但计算机内部对于无线死循环的数据,会根据一个标准保留52位。也就是说,计算机内部在存储0.1和0.2的时候,本来就不精准,两个不精准的小数在计算后,距离精准的结果是有一定误差的。

项目中碰到这种情况,有3种处理方法:

1.将小数乘以10的倍数,转为整数,然后计算,计算完成后,再缩小10的倍数,例如:

  var result = ((0.1 * 10) + (0.2 * 10)) / 10
  // result === 0.3

2.使用数字的toFixed方法,强制保留小数点后多少位,例:

  var result = (0.1 + 0.2).toFixed(2)
  // result === 0.30

3.自定义数字运算方法,当需要进行数学运算的时候,不直接进行,调用自定义的方法进行,例:(加法封装)

  function add(...args){
          var num = args.find(item => {
              if(item != 0 && !item){
              	 throw new Error("数学运算要使用数字")
              }
          })
          var arr = args.map(item => {
              var index = (item+'').indexOf('.')
              if(index >= 0){
                  return (item+'').split('.')[1].length
              }
          })
          arr = arr.filter(item => item)
          if(arr.length){
              var max = Math.max(...arr)
              var data = args.map(item => item * Math.pow(10, max))
              var data.reduce((a, b) => a + b) / Math.pow(10, max)
          }else{
              var data = args
              return data.reduce((a, b) => a + b)
          }
      }
      // 调用使用:
      var num1 = add(0.1, 0.2)
      console.log(num1); // 0.3
      
      var num2 = add(1, 2)
      console.log(num2); // 3
      
      var num3 = add(1, 2.1)
      console.log(num3); // 3.1

53.JS 如何实现多线程

我们都知道JS是一种单线程语言,即使是一些异步的事件也是在JS的主线程上运行的(具体是怎么运行的,可以看我另一篇博客JS代码运行机制)。像setTimeout、ajax的异步请求,或者是dom元素的一些事件,都是在JS主线程执行的,这些操作并没有在浏览器中开辟新的线程去执行,而是当这些异步操作被操作时或者是被触发时才进入事件队列,然后在JS主线程中开始运行。

首先说一下浏览器的线程,浏览器中主要的线程包括,UI渲染线程,JS主线程,GUI事件触发线程,http请求线程。

JS作为脚本语言,它的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。(这里这些问题我们不做研究)

但是单线程的语言,有一个很致命的确定。如果说一个脚本语言在执行时,其中某一块的功能在执行时耗费了大量的时间,那么就会造成阻塞。这样的项目,用户体验是非常差的,所以这种现象在项目的开发过程中是不允许存在的。

其实JS为我们提供了一个Worker的类,它的作用就是为了解决这种阻塞的现象。当我们使用这个类的时候,它就会向浏览器申请一个新的线程。这个线程就用来单独执行一个js文件。

var worker = new Worker(js文件路径);
那么这个语句就会申请一个线程用来执行这个js文件。这样也就实现了js的多线程。

54.常见的 HTTP 请求有哪些 ? 他们的区别是什么 ?

常见的有5种,分别是GET、HEAD, POST、PUT、 DELETE

GET:它是最常见的方法,用于获取资源,常用于向服务器查询某些信息。打开网页一般都是用GET方法,因为要从 Web 服务器获取信息
HEAD:类似于 GET请求,只不过返回的响应中没有具体的内容,用于获取报头。
POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件), 数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或对已有资源的修改。
PUT:从客户端向服务器传送的数据取代指定文档的内容。
DELETE:请求服务器删除指定的页面。

55.什么是高阶函数?

高阶函数英文叫Higher-order function。JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
常见的高阶函数:map、foreach、filter、sort等

55.JavaScript中的全局函数?
javascript中常见的全局函数有:
1.escape()函数,对字符串进行编码;
2.isNaN()函数,检查一个参数是否是非数字值;
3.Number()函数,把对象的值转换为数字;
4.String()函数,把对象的值转换为字符串;
5.encodeURI()函数,把字符串作为URI进行编码;
6.decodeURI()函数,解码某个编码的URL;
7.decodeURIComponent()函数,解码一个编码的URI组件;
8.encodeURIComponent()函数,把字符串编码为URI组件;
9.eval()函数,计算字符串,并执行其代码;
10.isFinite()函数,检查参数是否是无穷大;1
1.parseFloat()函数,解析字符串,返回浮点数;
12.parseInt()函数,解析字符串,返回整数;
13.unescape()函数,对escape()编码的字符串进行解码

注意:setTimeout和setInteval 都是window对象的定时方法,非JavaScript中自带的全局方法
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值