JS面试题

JavaScript 的数据类型有哪些

数据类型分为:基本数据类型 和 引人入数据类型
    基本数据类型: string number boolean undefined null symbol  BigInt 
    引入数据类型: Object

判断数组的方法有哪些

1.Arrar.isArray()
2.Object.prototype.toString.call(Array) === [object array]
3.[].constrtucor == Array
4.[] instanceof Array 
5. [].__proto__ === Array.prototype

null 和 undefined 的区别

null 和 undefined都是属于基本数据类型,总的来说的 都表示为空
null 直译过来就空的意思。 一般用于 对象不确定给什么值的时候,可以给个 null ,就不会执行内存的任何对象,把null表示未创建的对象
undefined 直译过来就是未定义,表示有这个变量但是没有赋值,

typeof null 的结果是什么,为什么

object 
这其实是js设计的一个缺陷,null并不是object的实例,是属于基本数据类型,在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型,null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回“object”。 但为什么不在以后修复这个bug呢 ,其实是有提案,但是现在恢复以及太晚了,

为什么 0.1 + 0.2 !== 0.3?

当计算 0.1 加 0.2 的时候 实际上就是把这两个数字转成 二进制来进行计算之后在转换成 十进制 ,这两个数字在转换成二级制的时候会出现无限 循环的情况 ,出现循环的情况,计算机也不会用无限的空间
去存这些无限的 0 和1 
JavaScript 中数字的存储遵循 IEEE 754 标准,是以 64 位双精度格式来存储数字的
我们只需要知道,在二进制科学表示法中,双精度浮点的小数部分最多只能保留 52 位(比如 1.xxx... * 2^n,小数点后的 x 最多保留 52 位),加上前面的1,其实就是保留 53 位有效数字,超过这个长度的位数会被舍去(会采用 0舍1入 的方式),这样就造成了精度丢失的问题。
0.1 + 0.2 由于两次存储时的精度丢失加上一次运算时的精度丢失,所以最终结果 0.1 + 0.2 !== 0.3。 可以利用 ES6 中的极小数 Number.EPSILON 来进行判断。

isNaN 和 Number.isNaN 函数的区别?

isNaN会通过Number方法,试图将字符串"测试"转换成Number类型,但转换失败了,因为 Number('测试') 的结果为NaN ,所以最后返回true。
而Number.isNaN方法,只是严格的判断传入的参数是否全等于NaN( '测试' === NaN) ,字符串当然不全等于NaN啦,所以输出false。

new操作符的实现步骤如下:

(1)首先创建了一个新的空对象
(2)设置原型,将对象的原型设置为函数的 prototype 对象。
(3)让函数的 this 指向这个对象,执行构造函数的代码(为这个新对象添加属性)
(4)判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。

对JSON的理解

 JSON是轻量级的文本数据交换格式,其实就是个字符串,JSON作用就是前后端交互方式,前端把数据转换符合JSON格式的数据转换成JSON字符串,后端通过JSON格式的字符串在转换成数据
 JS中提供两个函数来和JSON进行互相转换   
    JSON.parse() parse本来就是解析的意思,所以这个函数通常是把 JSON的格式的字符串转换成一个JS 的数据结构,
    JSON.stringify 函数,通过传入一个符合 JSON 格式的数据结构,将其转换为一个 JSON 字符串

垃圾回收

一个程序肯定是需要内存,我们在js中定义对象,变量这些都需要分配内存去存储,当这些变量和对象不使用的时候,就变会成垃圾,而怎么去回收呢,js是有自动垃圾回收机制的,js会定期对那些不在使用的变量、对象所占用的内存进行释放,在js中存在两种变量,局部变量和全局变量,全局变量的生命周期会在页面关闭时,而局部变量是在函数中,局部变量的生命周期是函数执行开始 到函数执行完毕,局部变量不再被使用,它们所占有的空间就会被释放
垃圾回收一般有两种方式,一种就是标志清除,第二种就是引用计数, 现在浏览器用于的垃圾回收方式都是标记清除,什么是标记清除呢,就是当一个变量进入环境会标记成 “进入环境”,一般来说进入环境的变量是不可被清除的内存的,因为变量是正在使用的,当变量离开时,就标记成“离开环境”,最后垃圾收集器完成内存清除工作,销毁那些带标记的值,并回收他们所占用的内存空间。
引用计数在ie老版本是用的这种回收机制,其实引用计数,顾名思义就是我a变量引用了 b变量,然后b被引入了嘛计数就变成1 ,依次类推,当然如果a不引用了b了,然我的计数就变成0,0就会被清除掉,之所以不用引入计数的原因就是,在函数中,两个对象相互引入,是肯定有计数的,结果函数都执行完了,应该讲是都会出栈的,然而两个对象相互引用,导致就不能在内存清除掉

== 和 ===区别,分别在什么情况使用

== 表示 如果两边的操作数相等 就会返回 true, 如果两边的数据不一样,会进行隐式转换
=== 只有两个操作数在不转换的前提下相等才返回 true。即类型相同,值也需相同
相等运算符隐藏的类型转换,会带来一些违反直觉的结果 所以,除了在比较对象属性为null或者undefined的情况下,我们可以使用相等操作符(==),其他情况建议一律使用全等操作符(===)

浅拷贝和深拷贝的区别和方法

说道浅拷贝和深拷贝就要说道类型数据存储,数据存储又分为两大数据,基本数据和引用数据,基本数据存储在栈内存中,引用数据类型存在在堆里面,
浅拷贝:其实对原始数据进行精确的拷贝,基本数据类型就拷贝基本类型的值,如果是引用类型,就拷贝地址  浅拷贝是拷贝一层,属性为对象时,浅拷贝是复制,两个对象指向同一个地址 浅拷贝的方法有:object assign 数组原型的slice, content,扩展运算符
深拷贝:开辟新的一个栈,两个对象完全相同,但是地址不同 ,修改一个对象属性不会影响另外一个对象属性 ,JSON.stringify(),还有使用递归来实现深拷贝

谈谈闭包的理解和使用场景

什么是: 其实闭包就是可以从内部函数访问外部函数的作用域
产生: 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数时),就产生了闭包,
理解:其实闭包可以延迟函数里面的变量的生命周期,可以时全局的作用域中访问函数里面的变量,去操控函数里面的变量,按道理讲函数执行完之后,应该被栈移除的,里面的局部变量也会被回收
mdn官方也说过 如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响。

typeof 与 instanceof 区别

typeof 会返回基本数据类型 instanceof是返回的布尔值
他们两个最大的区别还是 typeof 对用引用类型的只会返回 object  包括null ,只会检测到 function 
instanceof 可以准确判断复杂的引用数据类型,但不能判断基本数据类型
如果需要通用的检测数据类型,可以使用 Object.prototype.tostring.call

尾递归是什么,有什么作用

首先我们要知道递归是什么,无非就是在 函数里面在调用本身,而尾递归呢无非就是在尾部return调用,这样有什么好处呢,在递归中我们会反反复复的调用函数,触发递归的条件为false才会结束,这样造成的后果
就是说 我的执行栈函数一直不会出去,必须等到最后一个递归函数执行完毕,函数才会开始离开执行栈,递归次数过多容易造成栈溢出,使用尾递归为什么不会这样的,当调用一个函数,在使用尾递归就会返回
一个全新的函数去执行,也就不需要存储上一个函数了

事件代理是什么,应用场景

在js中有三个阶段  捕获-》目标-》冒泡 事件代理也叫做事件委托 事件代理其实就是运用了冒泡,把事件绑定在父元素,当click的时候通过冒泡给父元素触发事件,如果还想知道是谁触发的事件,还可以使用 
event.target 找到,事件代理的优点肯定就是,不用给子元素一个一个的绑定事件,直接给父元素绑定,提升了很多性能
focus blur 或者焦点和失去焦点是没有冒泡的,

原型链的作用

1.继承 2.实例对象能共享构造函数原型里面的方法 3 减少了方法的重复 每个实例只需使用构造函数的就可以了 4.减少了内存
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值