1. underfind出现的4种情况
- 声明未赋值
- 对象属性不存在
- 函数调用少了参数
- 函数的默认返回值
2. filter
current=>当前遍历值,index=>下标,array=>元数组- 特点:不会改变原数组
let arr = [1,2,3,4,5];
let newArr = arr.filter((current,index,array)=> current > 2)
console.log(arr); //[1,2,3,4,5]
console.log(newArr); //[3,4,5]
3. forEach和map
forEach特点- 没有返回值
- 不能被break中断
- 遍历的是value值
map特点- 有返回值,返回数组
- 不能被break中断
- 接受的参数为函数(value,index)
4. 递归 优化递归计算慢的问题:使用尾递归=>函数最后调用一个函数
// 求1~10的和
function sum(num1,num2){
let num = num1 + num2;
if(num2+1 > 10) return num;
return sum(num, num2+1)
}
let sums = sum(1,2)
5. 闭包
闭包是什么?=> 方法里面返回一个方法,有权访问另外一个函数作用域中的变量为什么要闭包- 为了在函数外部访问函数内部变量 (沟通内外部方法的桥梁)
- 保护私有变量不被内存回收机制回收(延长变量生命周期,不会造成全局污染)
- 创建私有环境
应用场景=> 防抖与节流(体现了闭包的延长生命周期)如何防止内存泄漏=> 在退出函数之前,将不使用的局部变量全部删除(str = null)
function fun1(){
let str = '闭包';
return function(){
return str;
}
}
6. 作用域链
- 就近原则查找
function a(){
let str = 1;
function b(){
let str = 2;
function c(){
console.log(str); // 2
}
}
}
7. 防抖与节流
什么是防抖=> 固定时间内,只允许请求一次例子Select下拉框数据根据框内输入动态获取,用户输的快数据获取容易发生抖动,设计一个定时器可以在两秒后发起请求。
什么是节流=> 一定时间内,将多个请求合并成一次请求什么时候用=> 提交表单,高频监听事件例子用户在提交资料时不停的点击提交,在一定时间内只处理用户的一次请求。
8. 原型与原型链
-
什么是原型=> prototype- 只有函数才有原型
例子=> function fun(){}; fun.prototype.(name || fun2)= '原型' || function(){}; //为什么要在原型上面赋值=> 为了原型链的继承
-
什么是原型链=> 两种展现形式老proto /新[[prototype]]- 任何数据如对象数组都有原型链
- 原型链继承是一层一层往上找,直到null,原型链最顶端为null
- 判断是否为函数私有属性 实例.hasOwnProperty(属性),会打印出私有属性
9. 值类型和引用类型
值类型
- 直接访问数据的值。
- 如(int float 布尔)
- 存储在栈中
- 初始值为0
- 继承自System.ValueType
引用类型
- 访问数据的存储地址
- 如(数组 对象)
- 值在堆中,地址在栈中
- 初始值为null
- 继承自System.Object。
10. 判断数据类型
typeof(基础数据类型)- array
instanceofArray(判断是否给定类型) constructorarr.constructor===Array(判断是否为某构造函数的实例)(constructor构造器:在对象创建或者实例化时候被调用的方法,用该方法来初始化数据和资源)
11. 编程方式
命令式编程=> 代码一步一步的执行函数式编程=> 把运算过程抽象成一个个函数,如(一个函数中有加和乘,函数式编程会写成两个函数,一个加,一个乘)特征:- 函数可以作为参数
- 可以作为函数的返回值
- 函数可以赋值给变量
- 函数是纯函数(纯函数特征:不依赖外部变量,不改变本身之外的变量)
- 函数组合compose => 将多个函数合并成一个函数
面向对象编程=> 把现实世界的事物抽象成类和对象模型,通过这些模型构建应用程序功能,描述一个类就去new一个类
12. arguments
- arguments是接收函数参数的一个类数组对象,我们叫他伪数组
- arguments.length传过来的函数参数个数
- arguments转成真的数组 [].slice.call(arguments);
- arguments[0] = 20; 修改值
- 接受参数的函数名.apply(this, arguments); 将参数传到另一个函数
- ES6 中可以用扩展运算符展开得到参数 ...arguments
13. this =>在js中代表的是作用域,遵循谁调用指向谁=>当前上级
14. .call()和.apply()和.bind()
- B.
call(A, args1);即A对象调用B对象的方法,改变this指向 - B.
apply(A, arguments),即A对象应用B对象的方法,改变this指向 bind()只改变this指向,不执行
15. 深拷贝和浅拷贝=>只适用于引用类型
深拷贝=> 在内存中重新创建储存空间, 不会改变原值- 解构赋值是不是深拷贝?=> 一维数组是深拷贝,二维是浅拷贝
- 日常用到的深拷贝,JSON.parse(),JSON.stringify()
- 弊端 => 不能拷贝所有的js关键字(如:null,function...)
- 手写深拷贝 => 1、定义一个变量判断是数组还是对象 2、通过for循环拷贝值(基本值直接复制,引用类型值使用递归)
浅拷贝=> 表示只拷贝了在内存中的地址 (例:let arr = [1,2]; arr.push(3)=> arr =[1,2,3])
16. 栈和堆
栈
- 先进后出
- 自动分配和释放内存空间
- 基本类型存在栈
堆
- 引用类型的值存在堆,地址存在栈(先去栈拿地址,再去堆取值)
- 在没有任何变量引用时会被垃圾回收机制回收
17.虚拟dom
意义=> 初始化生成虚拟dom,后续高效更新dom是什么=> 一个js对象作用=> 初始化时将真实dom转换成虚拟dom,之后通过对象对比更新真实dom- 虚拟dom对象比较是执行效率的快慢
- 操作真实dom会消耗浏览器性能
结构- 目标元素(谁的虚拟dom)
- 属性 (class style click)
- children 子元素
18.xss和csrf攻击
- XSS => 跨站脚本攻击 => 通过注入脚本获取信息 => 可以使用前后端分离,前端渲染,后端负责数据
- CSRF => 跨站请求伪造 => 使用cookie假冒用户进行操作 => 可以使用token,或者开启严格模式
19.解决跨域
JsonP=> 前端通过script发送一个get请求来解决,并且请求参数为一个函数Cors=> 后端通过添加请求头来解决
20. 宏任务和微任务 执行顺序:同步任务执行=>微任务执行=>宏任务
- 宏任务 => 如settimeout,promise
- 微任务 => 如promise.then()