前端八股文(JS篇)
目录
3.object.assign和扩展运算法是深拷贝还是浅拷贝,两者区别
1.数组有哪些原生方法?
- 数组和字符串的转换方法: toString(),toLocalString(),join(),其中join(方法可以指定转换为字符串时的分隔符。
- 数组尾部的操作的方法pop()和push(),push方法可以传入多个参数。
- 数组首部操作的方法shift()和unshift()重排序的方法reverse()和sort(),sort()方法可以传入一个函数来进行比较,传入前后两个值,如果返回值是正数,则交换两个参数的位置。
- 数组的连接的方法concat(),返回的是拼接好的数组,不影响原数组。
- 数组截取方法slice(),用于截取数组中的一部分返回,不影响原数组。
- 数值插入方法splice(),影响原数组查找特定项的索引的方法,indexOf()和lastIndexOf()迭代方法every(),some(),filter(),map(),和forEach()方法
- 数组归并方法reduce()和reduceRight()方法
- 改变原数组的方法:fill(),pop(),push(),shift(),splice(),unshift(),reverse(),sort();
- 不改变原数组的方法:concat(),every(),filter(),find(),findIndex(),forEach(),indeOf(),join(),lastIndexOf(),map(),reduce(),reduceRight(),slice(),some().
2.substring和substr的区别
它们都是字符串方法,用于截取字符串的一部分,主要区别在于参数不同
- substring(startIndex,endIndex):接收两个参数,一个起始索引和结束索引,来指定字符串范围,如果省略第二个参数,则截取到字符串末尾。
- substr(startIndex,length) :接收两个参数,并返回从startIndex开始,长度为length的子字符串。如果省略第二个参数,则截取到字符串末尾。
const str = "Hello, World!";
console.log(str.substring(0, 5)); // 输出: "Hello"
console.log(str.substr(7, 5)); // 输出: "World"
3.object.assign和扩展运算法是深拷贝还是浅拷贝,两者区别
都是浅拷贝
- object.assign()方法接收的第一个参数作为目标对象,后面的所有参数作为源对象。然后把所有的源对象合并到目标对象中。它会修改一个对象,因此会触发ES6setter
- 扩展操作符(...)使用它时,数组或对象中的每一个值都会被拷贝到一个新的数组或对象中。它不复制继承的属性或类的属性,但它会复制ES6的symbols属性
4.new操作符的实现原理
new操作符用来创建一个对象,并将该对象绑定到构造函数的this上。
new操作符的执行过程:
- 创建一个空对象
- 设置原型,将构造函数的原型指向空对象的prototype属性。
- 将this指向这个对象,通过apply执行构造函数。
- 判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象
5.for...in和for...of的区别
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对象。
6.对AJAX的理解,实现一个AJAX请求
AJAX是 Asynchronous JavaScript and XML 的缩写,指的是通过JavaScript的异步通信,从服务器获取xml文档从中提取数据,在更新当前网页的对应部分,而不用刷新整个网页。创建AJAX请求的步骤:
- 创建一个XMLHttpReuqest对象。
- 在这个对象使用open方法创建一个HTTP请求,open方法所需要的参数是请求的方法,请求的地址,是否异步和用户的认证信息。
- 在发起请求前,可以为这个对象添加一些信息和监听函数。比如说可以通过setRequestHeader方法来为请求添加头信息。还可以为这个对象添加一个状态监听函数。一个XMLHttpRequest对象一共有5个状态,当他的状态变化时会触发onreadystatechange事件,可以通过设置监听函数,来处理请求成功后的结果。当对象的readyState变为4的时候,代表服务器返回的数据接收完成,这个时候可以通过判断请求的状态,如果状态时2xx或者304的话代表返回值正常。这个时候就可以通过response中的数据来对页面进行更新了。
- 当对象的属性和监听函数设置完成后,最后调用send方法来向服务器发起请求,可以传入参数作为发送的数据体。
const SERVER_URL = "/server";
let xhr = new XMLHttpRequest();
// 创建 Http 请求
xhr.open("GET", url, true);
// 设置状态监听函数
xhr.onreadystatechange = function() {
if (this.readyState !== 4) return;
// 当请求成功时
if (this.status === 200) {
handle(this.response);
} else {
console.error(this.statusText);
}
};
// 设置请求失败时的监听函数
xhr.onerror = function() {
console.error(this.statusText);
};
// 设置请求头信息
xhr.responseType = "json";
xhr.setRequestHeader("Accept", "application/json");
// 发送 Http 请求
xhr.send(null);
7.ajax,axios,fetch的区别
ajax:
- 基于原生XHR开发,XHR本身架构不清晰。
- 针对MVC编程,不符合现在前端MVVM。
- 多个请求之间如果有先后关系,就会出现回调地狱
- 配置和调用方式非常混乱,而且基于事件的异步模型不友好
axios:
- 支持PromiseAPI
- 从浏览器中创建XMLHttpRequest
- 从node.js创建http请求
- 支持请求拦截和响应拦截
- 自动转换JSON数据
- 客服端支持防止CSRF/XSRF
fetch:
- 浏览器原生实现的请求方式,ajax的替代品
- 基于标准的Promise实现,支持async/await
- fetchtch只对网络请求报错,对400,500都当做请求成功,需要封装去处理
- 默认不会带cookie,需要添加配置项
- fetch没有办法原生监测请求的进度,而XHR可以。
8.forEach和map方法有什么区别
两个方法都是用来遍历循环数组,区别如下:
- forEach()对数据的操作会改变原数组,该方法没有返回值
- map()方法不会改变原数组的值,返回一个新数组,新数组中的值为原数组调用函数处理之后的值
9.什么是尾调用,使用尾调用有什么好处?
尾调用就是在函数的最后一步调用函数,在一个函数里调用另外一个函数会保留当前执行的上下文,如果在函数尾部调用,因为已经是函数最后一步,所以这时可以不用保留当前的执行上下文,从而节省内存。但是ES6的尾调用只能在严格模式下开启,正常模式是无效的。
10.你用过哪些设计模式
- 单例模式:保证类只有一个实例,并提供一个访问它的全局访问点。
- 工厂模式:用来创建对象,根据不同的参数返回不同的对象实例。
- 策略模式:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
- 装饰器模式:在不改变对象原型的基础上,对其进行包装扩展。
- 观察者模式:定义了对象间一种一对多关系,当目标对象状态发生改变时,所有依赖它对对象都会得到通知。
- 发布订阅模式: 基于一个主题/事件通道,希望接收通知的对象通过自定义事件订阅主题,被激活事件的对象(通过发布主题事件的方式被通知)。