JavaScript
Promise
一.数据结构
1.JavaScript 有哪些数据类型
共有八个数据类型,分别是undefined,Null,Boolean,String,Number,Object,Symbol,Bigint
这些数据类型可以分为原始数据类型与引用数据类型(复杂数据类型),他们在内存中的存储方式不同
其中 **Symbol** 和 **BigInt\*\* 是 ES6 中新增的数据类型:
- **
Symbol**代表创建后独一无二且不可变的数据类型,它主要是为了解决可能出现的全局变量冲突的问题。 - **
BigInt** 是一种数字类型的数据,它可以表示任意精度格式的整数,使用 BigInt 可以安全地存储和操作大整数,即使这个数已经超出了 Number 能够表示的安全整数范围。
堆: 存放引用数据类型,引用数据类型占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,如Object、Array、Function。栈: 存放原始数据类型,栈中的简单数据段,占据空间小,属于被频繁使用的数据,如String、Number、Null、Boolean。
- 堆: 存放引用数据类型,引用数据类型占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,如
Object、Array、Function。 - 栈: 存放原始数据类型,栈中的简单数据段,占据空间小,属于被频繁使用的数据,如
String、Number、Null、Boolean。
2.Undefined 与 Null 的区别
至少从三个方面来讲: 1.undefind是声明之后的默认值,而Null却不是
2.undefined代表的含义是未定义,而 null 代表的含义是空对象
3.undefined在 JavaScript 中不是一个保留字,这就意味着可以用 undefined 来作为一个变 量名字,null 是一个关键字
Undefined 和 Null 都是基本数据类型,这两个基本数据类型分别都只有一个值,就是 undefined 和 null。
- undefined 代表的含义是未定义,一般变量声明了但还没有定义的时候会返回
undefined,typeof为undefined - null 代表的含义是空对象,null 主要用于赋值给一些可能会返回对象的变量,作为初始化,
typeof为object
3.typeof null 的结果是什么,为什么?
4.为什么 0.1 + 0.2 ≠ 0.3,如何让其相等
因为浮点数运算的精度问题。在计算机运行过程中,需要将数据转化成二进制,然后再进行计算。 因为浮点数自身小数位数的限制而截断的二进制在转化为十进制,就变成 0.30000000000000004,所以在计算时会产生误差。
解决方法:
方法一:
首先转化为整数,相加之后再转化为小数.具体做法为先乘 10 相加后除以 10
1 2
| let x = (0.1 * 10 + 0.2 * 10) / 10; console.log(x === 0.3);
|
方法二:
使用number对象的toFixed方法,只保留一位小数点
5.typeof NaN会返回什么?
会返回Number,他表示一个不能表示的数字
6.for…in…与for…of…的区别
for…of… 遍历获取的是对象的键值,for…in…获取的是对象的键名
for...in和for...of都是JavaScript中的循环语句,而for…of 是 ES6 新增的遍历方式,允许遍历一个含有iterator接口的数据结构(数组、对象等)并且返回各项的值,和ES3中的for…in的区别如下
for…of 遍历获取的是对象的键值,for…in 获取的是对象的键名;for… in 会遍历对象的整个原型链,性能非常差不推荐使用,而 for … of 只遍历当前对象不会遍历原型链;- 对于数组的遍历,
for…in 会返回数组中所有可枚举的属性(包括原型链上可枚举的属性),for…of 只返回数组的下标对应的属性值;
总结:for...in 循环主要是为了遍历对象而生,不适用于遍历数组;for...of 循环可以用来遍历数组、类数组对象,字符串、Set、Map 以及 Generator 对象。
7.对 AJAX 的理解,实现一个 AJAX 请求
AJAX是 Asynchronous JavaScript and XML 的缩写,指的是通过 JavaScript 的 异步通信,从服务器获取 XML 文档从中提取数据,再更新当前网页的对应部分,而不用刷新整个网页。 创建AJAX请求的步骤:
- 创建一个
XMLHttpRequest 对象。 - 在这个对象上使用
open 方法创建一个 HTTP 请求,open 方法所需要的参数是请求的方法、请求的地址、是否异步和用户的认证信息。 - 在发起请求前,可以为这个对象添加一些信息和监听函数。比如说可以通过
setRequestHeader 方法来为请求添加头信息。还可以为这个对象添加一个状态监听函数。一个 XMLHttpRequest 对象一共有 5 个状态,当它的状态变化时会触发onreadystatechange 事件,可以通过设置监听函数,来处理请求成功后的结果。当对象的 readyState 变为 4 的时候,代表服务器返回的数据接收完成,这个时候可以通过判断请求的状态,如果状态是 2xx 或者 304 的话则代表返回正常。这个时候就可以通过 response 中的数据来对页面进行更新了。 - 当对象的属性和监听函数设置完成后,最后调用
send 方法来向服务器发起请求,可以传入参数作为发送的数据体。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| const serve_url = '/serve_url'
let xhr = new XMLHttpRequest()
xhr.open('GET', serve_url, true)
xhr.onreadystatechange = function(){ if(xhr.readyState !==4) { return } if(xhr.status ===200 ){ hander(this.response) }else[ console.error(this.statusText) ] }
xhr.onerror = function() { console.error(this.statusText) }
xhr.responseType = 'json' xhr.setRequestHeader('Content-Type', 'application/json')
xhr.send(
|
8.ajax,axios,fetch 的区别
ajax
- 基于原生
XHR开发,XHR本身架构不清晰。 - 针对MVC编程,不符合现在前端 MVVM 的浪潮。
- 多个请求之间如果有先后关系的话,就会出现回调地狱
- 配置和调用方式非常混乱,而且基于事件的异步模型不友好。
axios
- 支持
PromiseAPI - 从浏览器中创建
XMLHttpRequest - 从
node.js 创建 http 请求 - 支持请求拦截和响应拦截
- 自动转换
JSON数据 - 客服端支持防止
CSRF/XSRF
fetch
浏览器原生实现的请求方式,ajax 的替代品基于标准 Promise 实现,支持async/awaitfetchtch只对网络请求报错,对 400,500 都当做成功的请求,需要封装去处理默认不会带cookie,需要添加配置项fetch没有办法原生监测请求的进度,而XHR可以。
- 浏览器原生实现的请求方式,ajax 的替代品
- 基于标准
Promise 实现,支持async/await fetchtch只对网络请求报错,对 400,500 都当做成功的请求,需要封装去处理- 默认不会带
cookie,需要添加配置项 fetch没有办法原生监测请求的进度,而XHR可以。
9.forEach 和 map 的区别
两个方法都是用来遍历数组,区别如下:
forEach() 对数据的操作会改变原来的数据,这个方法没有返回值map() 方法不会改变原来数组的值,会返回一个新的数组,新的数组中的值是原来的数组进行处理后的值
10.什么是尾调用,使用尾调用有什么好处