目录
1、解释一下什么是闭包 ?
🍉
闭包:就是能够读取外层函数内部变量的函数。
🍉
闭包需要满足三个条件:
访问所在作用域;
函数嵌套;
在所在作用域外被调用 。
🍉
优点:
可以重复使用变量,并且不会造成变量污染 。
🍉
缺点:
会引起内存泄漏
🍉
使用闭包的注意点:
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE
中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象 (object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性 (private value),这时一定要小心,不要随便改变父函数内部变量的值。
2、解释一下原型和原型链 ?
🍉
原型
原型就是一个为对象实例定义了一些公共属性和公共方法的对象模板。
🍉
原型链
对象之间的继承关系通过构造函数的
prototype
指向父类对象,直到指向
Object
对象为止形成的指向链条。
通俗讲: 原型链是原型对象创建过程的历史记录。
🍉
注:在javascript中,所有的对象都拥有一个__proto__属性指向该对象的原型(prototype) 。
3、说一下 ES6 中你熟悉的一些内容 ?
🍉
class 类的继承
ES6
中不再像
ES5
一样使用原型链实现继承,而是引入
Class
这个概念
🍉
async、
await
使用
async/await,
搭配
promise,
可以通过编写形似同步的代码来处理异步流程
,
提高代码的简洁性和可读性async
用于申明一个
function
是异步的,而
await
用于等待一个异步方法执行完成
🍉
Promise是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理、强大
🍉
Symbol是一种基本类型。
Symbol
通过调用
symbol
函数产生,它接收一个可选的名字参数,该函数返回的symbol
是唯一的
🍉
Proxy代理使用代理(Proxy)监听对象的操作,然后可以做一些相应事情
🍉
Set是类似于数组的数据集合,无序,插入删除速度快,元素不重复,查找速度快。
🍉
Map是一个类似对象的数据结构,和对象不同的在于它的
key
可以是任意类型,但是对象只能使用string和symbol
类型,
Map
的存储关联性更强
🍉
生成器函数可以进行阻断函数执行的过程,通过传参可以传入新的值进入函数继续执行,可以用于将异步变为阻塞式同步
4、数组排序的方式 ?
🍉 冒泡排序:
<script>
for(var i=0;i<arr.length-1;i++){
for(var j=0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
var temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
if(arr[j]===arr[j-1]) i++;
}
</script>
🍉 选择排序:
<script>
for(var i=0;i<arr.length;i++){
var min=i;
for(var j=i+1;j<arr.length;j++){
if(arr[j]<arr[min]) min=j;
}
if(min!==i){
var temp=arr[i];
arr[i]=arr[min];
arr[min]=temp;
}
if(arr[i]===arr[i+1])i++;
}
</script>
🍉 快速排序:
<script>
function quickSort(arr) {
if (arr.length <= 1) return arr;
var centerIndex = ~~(arr.length / 2);
var left = [];
var right = [];
for (var i = 0; i < arr.length; i++) {
if (i === centerIndex) continue;
if (arr[i] < arr[centerIndex]) left.push(arr[i]);
else right.push(arr[i]);
}
return quickSort(left).concat(arr[centerIndex], quickSort(right));
}
</script>
5、什么是事件轮询(EventLoop) ?
🍉
一个用来等待和发送消息和事件的程序结构。
1
、所有任务都在主线程上执行,形成一个执行栈。
2
、主线程发现有异步任务,如果是微任务就把他放到微任务的消息队列里,如果是宏任务就把他放到宏任务的消息队列里。
3
、执行栈所有同步任务执行完毕。
4
、执行微任务队列,之后再执行宏任务队列。
5
、轮询第
4
步。
6、数组的一些API, 哪些能够改变原数组, 那些不能 ?
🍉 改变原数组的方法:
shift()unshift()pop()push()reverse()sort ()splice()
🍉 不改变原数组的方法:
concat()every()filter()forEach()indexOf()join()lastIndexOf()map()some()every()slice()reduce()reduceRight()flat()flatMap()find ()
7、for 循环与 forEach 的区别 ?
1.for
循环可以使用
break
跳出循环,但
forEach
不能。
2.for
循环可以控制循环起点(i初始化的数字决定循环的起点),
forEach
只能默认从索引
0
开始。
3.for
循环过程中支持修改索引(修改
i
),但
forEach
做不到(底层控制
index
自增,无法左右它)。
8、url 的组成 ?
http:/https: 协议www.baidu.com 域名:8080 端口/sf/vsearch 路径?wd = 百度热搜 查询 ( 可有可无 )#a=1&b=2 哈希值 ( 可有可无 )
9、Promise 的使用场景 ?
🍉
场景1
:获取文件信息
🍉
场景2
:配合
AJAX
获取信息
🍉
场景3
:解决回调地狱,实现串行任务队列
🍉
场景4: node
中进行本地操作的异步过程
10、let, const, var 的区别 ?
声明方式 变量提升 暂时性死区 重复声明 初始值 作用域var 允许 不存在 允许 不需要 非块级let 不允许 存在 不允许 不需要 块级const 不允许 存在 不允许 需要 块级