js面试题

1.call apply bind区别

共同点:都可以修改this,第一个参数都是修改的this

不同点

  1. 传参方式不同:
  • call是逐一传参,apply是数组/伪数组传参;call,apply是一次性传入,bind分为多次传入(参数1,参数2…)
  • 函数名.call(修改的this,参数1,参数2…)
  • 函数名.apply(修改的this,数组/伪数组)
  • 传入第一个参数为null,undefined,this指向window
  1. 执行机制不同:
  • call和apply会立即执行函数临时改变this一次;bind不会立即执行,bind会得到一个永久改变this指向的新函数

2.typeof和instanceof区别

  1. 使用 typeof 可以检测数据类型是基本数据类型还是引用数据类型,typeof null 返回的一个 object,是 js 中的 bug,他不是一个引用数据类型.现在 null 被认为是对象的占位符 技术上来说他仍然是个原始值 被 ECMAScript 沿用
  2. instanceof 是检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

typeofinstanceof都是判断数据类型的方法,区别如下:

  • typeof会返回一个变量的基本类型,instanceof返回的是一个布尔值
  • instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
  • typeof 也存在弊端,它虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了function 类型以外,其他的也无法判断

可以看到,上述两种方法都有弊端,并不能满足所有场景的需求

如果需要通用检测数据类型,可以采用Object.prototype.toString,调用该方法,统一返回格式“[object Xxx]”的字符串

3.事件委托

事件委托就是给父元素注册事件,利用事件冒泡的原理委托子元素处理,冒泡到父元素身上触发父元素事件

优点:减少注册事件,提高程序的性能

4.new关键字做了哪些事情?

  1. 创建新对象
  2. 构造函数this指向新对象
  3. 执行构造函数代码,修改this,添加新的属性
  4. 返回新对象

5.防抖和节流的异同点

  1. 相同点:都是减少事件触发的次数,从而提高网页的性能

  2. 不同点:场景不同

    • 防抖:减少用户主动触发的事件(输入框输入,鼠标移入事件)
    • 节流:事件本身高频触发(滚动事件,鼠标移动事件)

函数防抖:单位时间内,频繁触发事件,以最后一次为准(京东搜索框)

函数节流:单位时间内,频繁触发事件,只会执行一次(滚动事件)

6.ES6 里 let 和 var 的区别

var

使用var声明的变量存在变量提升
在函数中使用var声明变量的时候,该变量是局部
在函数内使用var,该变量是全局

1.块级作用域

var不存在块级作用域

let const 不存在变量提升,存在块级作用域

2.重复声明

var允许重复声明变量

letconst在同一作用域不允许重复声明变量

3.修改声明的变量

varlet可以

const声明一个只读的常量。一旦声明,常量的值就不能改变

4.使用

能用const的情况尽量使用const,其他情况下大多数使用let,避免使用var

7. =====的区别

==:比较两边的值是否相等

===:比较等号两边的值和数据类型是否相等

相等操作符(==)会做类型转换,再进行值的比较,全等运算符不会做类型转换

nullundefined 比较,相等操作符(==)为true,全等为false

8. null 和 undefined 的区别

null:空对象

undefined:未定义

null经过数字转换是0

undefined经过数字转换是Nan

9.原型链

作用域就是起作用的一个区域

作用域链:遵守一个就近原则,当使用一个变量的时候,会在当前作用域下寻找这个变量,如果没有找到,就去它上层作用域查找,直到找到这个变量或查

找到全局作用域,如果全局找不到这个变量的话,会报错.

10.闭包

闭包就是内层函数访问外层函数的变量就会形成闭包

作用:扩展变量的作用范围,封闭数据,防止变量污染

缺点:容易造成内存泄漏,占据内存

解决方案:在用完这个变量之后,给这个变量赋值为 null,利用 js 垃圾回收机制自动回收

内存泄漏一般是指变量的内存没有及时的回收,导致内存资源浪费。一般有三种情况出现内存泄露比较多。(1)常见的声明了一个全局变量,但是又没有用上,那么就有点浪费内存了,(2)定时器没清除 (3)循环引用:A 对象里面有一个属性指向 B 对象,B 对象有一个属性指向 A 对象。互相引用

解决内存泄露:我们编译器有一个自动的内存清理。常见的主要是引用记数 和 标记清除。 谷歌浏览器主要是用标记清除,大概流程是给每一个变量添加一个标记,通过内部算法计算引用情况,当不使用的时候就会自动清除。如果遇到定时器的话,我一般会在页面关闭的时候手动清除。如果遇到循环引用,我一般会手动把变量赋值为 null 来清除

11.浅拷贝与深拷贝

浅拷贝:拷贝基本数据类型为他的,拷贝引用数据类型为地址,生成新的数据,修改新的数据会影响原数据,实际开发常用的方法有:object.assgin,扩展运算符等等

深拷贝:在内存中开辟一个新的栈空间保存新的数据,修改新数据不会影响到原数据,开发中常用的方法有:loadsh 中的_.cloneDeep()方法,JSON.stringify()

12.for in与for of区别

  1. 功能不同:forin 是遍历数组下标,forof 是遍历数组元素
  2. 原型属性不同:forin 会遍历原型的元素 ,forof 不会遍历原型的元素
  3. 数据类型不同:forin 可以遍历 object 类型,forof 不可以遍历 object 类型

13.对原型的理解

在js中,原型是一个对象,通过原型可以实现对象的属性继承,函数对象都包含了Prototype内部属性,这个属性对应的是函数对象的构造函数,作为内部属性,prototype是不能被直接访问到的.为了方便查看一个对象的原型,火狐和谷歌内核的js引擎提供了一个叫proto的非标准的访问器.

14.原型链

当访问对象的某个属性时,会在当前对象属性进行查找,如果查找不到,就回去该对象的__proto__原型上查找(构造函数的prototype属性查找),如果还没有查找到,就会查找他的object对象原型上查找,一层层向上查找形成原型链.

作用:面向对象继承

对象访问原则:就近原则

15.this指向

  1. 以函数形式调用时,this---->window
  2. 以方法形式调用时,this---->调用方法的对象(例:obj.say())
  3. 在构造函数内,this 指向实例化对象
  4. 箭头函数内,没有 this 指向,它会去他的上一层寻找 this 指向
  5. 定时器中this—>window
  6. 使用call,apply调用时,this指向那个对象

16.谈谈对Promise的理解?

promise是ES6新增的一个构造函数,promise主要是用来解决开发中的回调地狱问题

它的工作流程是:当我们创建promise的时候,它就会立即执行里面的异步代码,此时它的状态是进行中,然后剩下两种状态是由异步本身决定的,分别对应的是异步操作的成功和失败,当成功或失败之后,promise的状态就会发生改变,从进行中到成功或者从进行中到失败,这时候就会分别调用它的resolve()和reject()方法来处理异步的结果,resolve()就会执行promise实例的then方法,reject就会执行promise实例的catch()方法,这就是整个流程。

promise本身并没有改变异步的顺序, 而是通过操作异步结果的顺序从而间接控制异步的顺序

17.promise是怎么解决回调地狱问题的?

promise是通过在上一个promise实例的then方法里面返回下一个promise实例,形成then的链式调用来解决异步回调地狱问题的。

18.异步函数是怎么用的?

用async关键字来修饰function函数,修饰的作用是为了在函数内部使用await关键字,然后用await来调用一个函数,那么await得到的结果就是就是这个函数then里面的res。

19.事件循环

  1. 事件循环(Event Loop)是js编译器解析与执行代码的一种规则.

js代码分为两大类:
(1)同步
(2)异步分为两种:

  • 异步宏:script标签 、事件处理函数、定时器回调、ajax回调
  • 异步微:promise.then()、await/async
  1. 事件循环规则:

    (1)先解析默认script标签,进入第一个宏任务(默认宏)

    (2)判断代码是同步还是异步

    (3)如果是同步,立即执行

    (4)如果是异步:微任务放入微队列,宏任务放入宏队列

    (5)当前同步执行完毕之后,开始执行异步队列

    (6)先清空微任务队列,之后再解析宏任务队列,此时完成一次事件循环

    (7)按照以上步骤反复解析执行每一个宏任务(事件循环就是按照相同的规则反复循环解析执行代码)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值