1. JavaScript 有哪些基本数据类型
解析:
BigInt:表示任意大的整数
答案:Undefined、Null、Boolean、Number、String、Symbol、BigInt。
2. 向上取整和向下取整是哪两个方法
解析
Math.ceil()向上取整Math.floor()向下取整Math.round()四舍五入Math.abs()绝对值
答案:Math.ceil() 向上取整、Math.floor() 向下取整
3. JavaScript 数据类型检测的方式有哪些
解析:
typeof运算符:typeof运算符可以用于检测一个值的数据类型。它返回一个表示数据类型的字符串,如"string"、"number"、"boolean"、"function"等。但它对于null和数组类型检测不准确。instanceof运算符:instanceof运算符用于检测一个对象是否属于某个类或构造函数的实例。它返回一个布尔值,表示对象是否属于该类的实例。但其不能检测基本数据类型,不能跨iframeconstructor属性:每个 JavaScript 对象都有一个constructor属性,用于指向创建该对象的构造函数。可以通过obj.constructor来检测对象的构造函数,从而判断对象的类型。但其能被修改。Object.prototype.toString方法:Object.prototype.toString是一个通用的方法,可以用于检测任意对象的数据类型。Array.isArray方法:Array.isArray是一个用于判断一个值是否为数组的静态方法。它返回一个布尔值,表示该值是否为数组类型。
答案:
typeof:只能检测出除null外的基本数据类型和functioninstanceof:能检测出引用类型,缺点:不能检测出基本类型,且不能跨iframeconstructor:基本能检测除了null和undefined的所有类型,缺点:constructor易被修改,也不能跨iframeObject.prototype.toString.call:检测出所有的类型
4. Object.prototype.toString.call 检测数据类型有什么缺点
解析: 它返回一个以"[object 类型]"形式表示对象类型的字符串。但返回的值受
Symbol.toStringTag的影响,如果Symbol.toStringTag值为一个字符串,“[object 类型]”中的类型为该属性值。
答案: Symbol.toStringTag 会影响 Object.prototype.toString.call 的返回值。
5. == 和 === 运算符有什么区别
答案:
==运算符进行类型转换,然后比较值是否相等。===运算符不进行类型转换,比较值和类型是否严格相等。
6. == 操作符的强制类型转换规则是什么
答案:
- 数据类型转换
boolean值得判断都会先转换为number在判断,数字优先级最高,然后是字符串。 null和undefined除了和彼此比较以外,与其他任何类型操作数进行相等性测试都为false。
7. Object.is 和 === 的区别
解析:
===是一种严格相等运算符,用于判断两个值是否完全相等。Object.is是一种“绝对相等”的比较方法,更严格一些,并且对于NaN和+0/-0的情况有不同的处理。在Object.is中,NaN被认为与自己相等,这是与===不同的地方。此外,Object.is还将+0和-0视为不相等,而===将它们视为相等。
答案:
Object.is(NaN,NaN)为true,NaN===NaN为falseObject.is(+0,-0)为false,+0===-0为true
8. JavaScript 判断数组的方式
答案:
- 通过
Object.prototype.toString.call()做判断 - 通过
Array.isArray()做判断 - 通过
instanceof做判断
9. JavaScript 是静态作用域还是动态作用域
解析: JavaScript 是静态作用域,在静态作用域中,作用域是由程序中变量和函数在编译阶段确定的,并在运行时保持不变。作用域链是根据代码中变量和函数定义的位置来确定的,与函数的实际调用位置无关。
答案:JavaScript 是静态作用域
10. null 和 undefined 区别
答案:null 来表示一个有意设置为空的值,而 undefined 则表示一个未定义的值
11. 变量提升与函数提升的区别?
答案:变量提升和函数提升都是提升到作用域的顶部,函数提升的优先级大于变量提升的优先级
12. typeof null 的结果为什么是 Object?
答案:Javascript 早期留下来的 bug,null 的二进制表示是 000 和 Object 类型一样,因此返回 Object
13. 什么是临时死区?
解析: 使用
let和const关字声明变量时,在声明之前会将变量放入“临时死区”中,访问该变量会抛出ReferenceError错误,从而阻止变量提升。
答案:使用 let 和 const 关字声明的变量不会被提升,在声明之前会将变量放入“临时死区”。
14. 会转换为假值的有哪些
答案:undefined 、 null 、 false 、 0 和 NaN 、 ""
15. 如何获取安全的 undefined 值?
解析:
undefined可以作为变量声明,可以通过void 0来获取安全的undefined值
答案:void 0
16. 什么是高阶函数
答案:一个函数作为参数或返回值的函数
17. typeof NaN 的结果是什么?
答案:number
18. isNaN 和 Number.isNaN 函数的区别
答案:isNaN() 将参数转换为数值,Number.isNaN() 不会。
19. 什么是闭包
解析: 函数内部声明的嵌套函数能够访问外部函数的变量。脚本执行时会将要执行函数放入执行栈中,同时产生执行上下文放入栈中,函数执行完了执行上下文出栈回收。但其他函数用到执行上下文时,就不会出栈释放,也就形成了闭包。
答案:闭包是指函数内部声明的嵌套函数能够访问外包函数变量。
20. 闭包的作用
答案:
- 创建私有变量
- 让变量保留在内存中
- 柯里化
21. 闭包的使用场景
答案:
- 高阶函数(回调函数,return 一个函数)
- 自执行函数
- 节流防抖
- 函数柯里化
- 函数回调
22. 闭包的缺点
答案:内存泄漏,使用完闭包函数后手动释放。
23. 执行上下文
解析: 执行上下文 可以理解为当前代码的执行环境,同一个函数在不同的环境中执行,会因为访问数据的不同产生不一样的结果。
答案:
- 全局执行上下文:只有一个,程序首次运行时创建,它会在浏览器中创建一个全局对象(
window对象),使this指向这个全局对象 - 函数执行上下文:函数被调用时创建,每次调用都会为该函数创建一个新的执行上下文
- Eval 函数执行上下文:运行
eval函数中的代码时创建的执行上下文,少用且不建议使用
答案:执行上下文是函数代码的执行环境,分为全局执行上下文、函数执行上下文、eval 函数执行上下文三种。
24. 执行栈
答案:脚本执行时会将要执行函数放入执行栈中,同时产生执行上下文放入栈中,函数执行完了执行上下文出栈回收
25. this 的理解
答案:
- 函数执行时,
this指向全局对象 - 方法调用时,
this指向调用这个方法的对象 - 构造函数调用时,
this指向新创建的对象 apply、call、bind调用,this 指向第一个参数的对象,如果第一个参数是null那指向全局对象。- 箭头函数时,
this执行函数声明时所在上下文的this值。
26. forEach 如何跳出循环?
解析:
forEach参数是回调函数因此break和return都无法跳槽循环,可以使用try catch捕获异常来跳出循环
答案:try catch
27. 什么是尾调用,使用尾调用有什么好处?
答案:
尾调用是指一个函数的最后一条语句是调用另一个函数,好处:
- 尾调用可以重用当前函数的调用帧,而不会增加额外的堆栈空间。
- 尾调用因为是最后一步执行函数,因此不必再保存当前的执行上下文。
尾调用只在严格模式下才会被优化,而在正常模式下无效。
28. forEach 和 map 方法的区别?
答案:
forEach遍历数组,没有返回值,如果遍历的元素是引用类型,可以改变元素的属性值map遍历数组,返回一个新数组,新数组中的值为回调函数的返回值,遍历的元素是引用类型,也可以改变元素的属性值。
29. includes 比 indexOf 好在哪?
解析:
includes内部使用了Number.isNaN对NaN进行了匹配
答案:includes 可以检测 NaN,indexOf 不能检测 NaN。
30. intanceof 操作符的作用是什么?
答案:instanceof 运算符用于判断构造函数的 prototype 属性是否出现在对象的原型链中的任何位置