1、JS的数据类型
1、JS的数据类型可以分为基本数据类型和引用类型
基本数据类型有:String(字符串)、Number(数值)、Boolean(布尔值)、null()、undefined(未定义)、ES6中新添加了Symbol(唯一值)、binInt(大的整数值)
引用类型有:Object(对象)、Function(函数)、Date(日期)、RegExp(正则)、Array(数组)
基本数据类型与引用数据类型的区别:
1、基本数据类型存放到栈中,引用数据类型存放到堆中
2、基本数据类型比较的是值,引用数据类型比较的是是否指向同一个地址
2、null与undefined的区别
null表示为值为空的对象,指向的是一个空对象,转为数值为0
undefined表示为未定义的值,当变量声明了但没有定义的时候,应为undefined
相同点:它们都是值为空的,==的时候为true
不同点:类型不一样,null的数据类型为Object,undefined的数据类型为undefined,===为false
3、检测数据类型的方法
- 1、typeof:检测数据类型,基本数据类型可以检测出来,但引用类型不能细分,都为Obejct
- 2、instanceof:比较数据类型
- 3、constructor:获取当前构造器
- 4、Object.prototype.toString().call:获取当前实例所有的类信息(最为准确)
4、==
与===
的区别
- 1、
==
是等于,它会比较值,如果类型不一样,它会强制转换后再比较值 - 2、
===
是全等于,类型和值都会比较,不会强制转换,其中有一个不同,均为false
5、作用域和作用域链
一个变量的使用范围就叫做作用域,作用域可以分为全局作用域和局部作用域。
一个HTML就是一个全局作用域,一个函数就是一个局部作用域。
当查找对象的某个属性时,先会查找它当前的内部作用域,如果没有找到就往上一层作用域找,一直找到全局作用域,这个链式查找的过程就叫做作用域链。
6、判断数组类型的方法
- 1、Array.isArray();
- 2、arr.constructor.toString().indexOf(‘Array’)
- 3、Object.prototype.toString().call(arr)
7、宏任务与微任务
JS的异步任务可以分为宏任务与微任务
宏任务有setInterval、setTimeOut计时器、Ajax
微任务就是promise.then、promise.catch、promise.finally
宏任务与微任务的执行操作顺序为:
1、当一个宏任务进行时,它会观察是否有微任务
2、如果有微任务,当这个宏任务完成之后,就会立即处理当前所有的微任务
3、当所有的微任务完成后,才进行下一个的宏任务
4、所以微任务优先,宏任务与微任务交替执行。
8、new对象的操作过程
- 1、创建一个新的对象
- 2、构造函数指向这个对象
- 3、执行这个构造函数的所有代码
- 4、返回这个新的对象
9、闭包
函数里面嵌套一个函数,里面的函数就叫做闭包。
优点:闭包可以调用外层函数的变量,实现数据共享,变量始终保持在内存之中,延长变量的生命周期。
缺点:闭包执行完之后,外层函数的变量不会被销毁,而是存放在内存中,容易信息泄露,所以如果没有用的信息的话,就删除掉,减少内存损耗。
闭包的应用场景:防抖、节流
10、原型与原型链
原型就是一个对象,原型对象可以分为显性原型对象和隐性原型对象。
显性原型对象就是prototype,它是函数对象所特有的,指向Object。
隐性原型对象就是__proto__,它是所有对象都拥有的,对象的隐性原型对象指向它的构造函数的显性原型对象。
原型链就是:当查找对象的属性或者方法的时候,就会在对象内部找,如果没有,就通过隐性原型对象这条链,指向构造函数的显性原型对象,就在构造函数里面找,如果没有找到就通过显性原型对象这条链,指向Object,直到找到为止,这个链式查找的过程,就叫做原型链
11、为什么0.1+0.2!=0.3,如何相等?
- 因为精度缺失,浮点数相加要转为二进制,然而存储空间并没有这么大,所以需要进1去0,导入二进制相加精度缺失,所以0.1+0.2!=0.3
- 解决方案:可以变成整数后相加,再返回浮点数。
12、回调函数
一个函数被作为参数被另一个函数所调用,这个函数就叫做回调函数。
简单来说,就是你定义了一个函数,但是你没有立即使用它,而是用另一个函数调用它,这就叫做回调函数。
优点:业务逻辑分离,耦合性降低。
缺点:回调函数以前被用来执行异步操作,这样的话,异步操作增多,就会不断嵌套,造成回调地狱,观赏和维持起来很难,所以ES6新添加了一个Promise对象来解决这个回调地狱问题。
13、Promise对象
Promise对象是ES6新添加的一个用来处理异步操作的对象。
Promise有3个状态:pending(进行中)、fulfilled(已完成)、rejected(已失败)
Promise有2个特点:
1、它的状态不受外界的影响
2、它的状态变化只能有2种1,一种是从pending转为resolved,一种是从pending转为rejected。
Promise的好处:
1、比传统的回调函数更加规范化
2、支持链式调用,有效解决了回调地狱问题
14、递归
- 函数内部调用自己,就叫做递归。
- 递归有两个条件,一个是自己调用自己,一个是要有结束条件,返回之前的所有结果。
- 最常见的应用场景就是阶乘,如求5的阶乘就返回5相乘,再返回调用自己(n-1),直结束条件为1,返回之前相乘的数,实现5的阶乘。
15、变量提升和函数提升
在JS编译过程中,会把变量的声明语句提到作用域的最顶部,实现变量提升。函数提升也是一样的。
这样的好处就是:
1、一次性编译完成,下次调用的时候就不用再编译,优化性能。
2、防止出错,可以先调用再声明也不会报错。(不推荐,还是严格遵守,先声明后定义,所以ES6新添加了let)