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
- 支持
Promise
API - 从浏览器中创建
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.什么是尾调用,使用尾调用有什么好处