js常见面试题

简介: js常见面试题

01 - 数据类型

值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对空(Null)、未定义(Undefined)、Symbol。

引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。


02 - 检测数据类型

type of

可以正常检测出:number、boolean、string、object、function、undefined、symbol、bigint

  • 检测基本数据类型,null会检测object,因为null是一个空的引用对象
  • 检测复杂数据类型,除function外,均为object


instanceof

instanceof运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

注意:只能检测复杂数据类型


toString

toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型

对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。

Object.prototype.toString.call('') ;  // [object String]
Object.prototype.toString.call(1) ;   // [object Number]


constructor
代表获取由哪个构造函数创建而出,可以检测出字面量方式创建的对象类型,因为字面方式创建,实际由对应类创建而出
不是字面量的方式只会获取到构造函数
 const dog = new Animal('大黄')
    console.log(dog.constructor === Object) // false
    console.log(dog.constructor === Animal) // true


isArray可以检测出是否为数组


03 - 作用域

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。

作用域的作用:

  • 提高了程序逻辑的局部性。
  • 增强了程序的可靠性,减少了名字冲突。


JavaScript(es6前)中的作用域有两种:


全局作用域

作用于所有代码执行的环境(整个 script 标签内部)或者一个独立的 js 文件。


  • 局部作用域(函数作用域)
  • JS没有块级作用域(Es6之前)


04 - 作用域链

只要是代码都在一个作用域中,写在函数内部的局部作用域,未写在任何函数内部即在全局作用域中;如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域;根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链


05 - 原型链和成员的查找机制

任何对象都有原型对象,也就是prototype属性,任何原型对象也是一个对象,该对象就有__proto__属性,这样一层一层往上找,就形成了一条链,我们称此为原型链;

当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性。
如果没有就查找它的原型(也就是 __proto__指向的 prototype 原型对象)。
如果还没有就查找原型对象的原型(Object的原型对象)。
依此类推一直找到 Object 为止(null)。
__proto__对象原型的意义就在于为对象成员查找机制提供一个方向,或者说一条路线。


06 - 谈谈你对 this 的理解?

this 是一个在运行时才进行绑定的引用,在不同的情况下它可能会被绑定不同的对象。


默认绑定 (指向 window 的情况) (函数调用模式 fn() )

默认情况下,this 会被绑定到全局对象上,比如在浏览器环境中就为window对象,在 node.js 环境下为global对象。

隐式绑定 (谁调用, this 指向谁) (方法调用模式 obj.fn() )

如果函数的调用是从对象上发起时,则该函数中的 this 会被自动隐式绑定为对象

显式绑定 (又叫做硬绑定) (上下文调用模式, 想让 this 指向谁, this 就指向谁)

硬绑定 => call apply bind

new 绑定 (构造函数模式)

另外,在使用 new 创建对象时也会进行 this 绑定

当使用 new 调用构造函数时,会创建一个新的对象并将该对象绑定到构造函数的 this


07 - 箭头函数中的 this 指向什么?

箭头函数不同于传统函数,它其实没有属于⾃⼰的 this

它所谓的 this 是, 捕获其外层 上下⽂的 this 值作为⾃⼰的 this 值。

并且由于箭头函数没有属于⾃⼰的 this ,它是不能被 new 调⽤的。


08 - 如何判断是否是数组?

方法一:使用 toString 方法

function isArray(arg) {
  return Object.prototype.toString.call(arg) === '[object Array]'
}
let arr = [1, 2, 3]
isArray(arr) // true

方法二:使用 ES6 新增的 Array.isArray 方法


09 - async/await 是什么?


ES7 标准中新增的 async 函数,从目前的内部实现来说其实就是 Generator 函数的语法糖。

它基于 Promise,并与所有现存的基于 Promise 的 API 兼容。


async 关键字

  1. async 关键字用于声明⼀个异步函数(如 async function asyncTask1() {...}
  2. async 会⾃动将常规函数转换成 Promise,返回值也是⼀个 Promise 对象
  3. async 函数内部可以使⽤ await


await 关键字

  1. await 用于等待异步的功能执⾏完毕 var result = await someAsyncCall()
  2. await 放置在 Promise 调⽤之前,会强制 async 函数中其他代码等待,直到 Promise 完成并返回结果
  3. await 只能与 Promise ⼀起使⽤
  4. await 只能在 async 函数内部使⽤


10、Promise 的理解

Promise 是一种为了避免回调地狱的异步解决方案


Promise 是一种状态: pending(进行中)、resolve(已成功)和rejected(已失败) 只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态


Promise的状态一旦改变,就不会再变,任何时候都可以得到这个结果,状态不可以逆,只能由 pending变成resolve或者由pending变成rejected


Promise 是一个构造函数


Promise 构造函数原型上的方法,可以通过创建一个 Promise 实例进行调用

  • Promise.prototype.then()
  • Promise.prototype.catch()
  • Promise.prototype.finally()


Promise 构造函数原型上的方法,可以通过创建一个 Promise 实例进行调用


1-1、静态方法-all

Promise.all()参数可以传递一个数组,数组中记录所有的 promise 异步处理

返回值是一个 Promise 的实例对象 then 方法可以获取到所有的 promise 异步处理的结果,一旦有某一个调用执行了 reject,则终止进入 catch


1-2、静态方法-allSettled

Promise.all 和 allSettled 基本一样,区别是,then 始终可以获取到异步的状态,哪怕其中有一个失败


1-3、静态方法-race

Promise.race 使用和 all 一样,但是只返回第一个结果,不管成功或失败


1-3、静态方法-any

Promise.any 返回第一个成功的结果


11、箭头函数和普通函数的区别

箭头函数与普通函数的区别在于:

1、箭头函数没有this,所以需要通过查找作用域链来确定this的值,这就意味着如果箭头函数被非箭头函数包含,this绑定的就是最近一层非箭头函数的this,


2、箭头函数没有自己的arguments对象,但是可以访问外围函数的arguments对象


3、不能通过new关键字调用,同样也没有new.target值和原型


1、语法更加简洁、清晰

2、箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承 this。

3、箭头函数继承而来的this指向永远不变

4、.call()/.apply()/.bind()无法改变箭头函数中this的指向

5、箭头函数不能作为构造函数使用

6、箭头函数没有自己的arguments,可以在箭头函数中使用rest参数代替 arguments对象,来访问箭头函数的参数列表

7、箭头函数没有原型prototype

8、箭头函数不能用作Generator函数,不能使用yeild关键字

9、箭头函数不具有super,不具有new.target


目录
相关文章
|
4月前
|
JSON JavaScript 前端开发
Javascript基础 86个面试题汇总 (附答案)
该文章汇总了JavaScript的基础面试题及其答案,涵盖了JavaScript的核心概念、特性以及常见的面试问题。
72 3
|
4月前
|
前端开发 JavaScript
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
JavaScript 面试系列:如何理解 ES6 中 Generator ?常用使用场景有哪些?
|
5月前
|
JavaScript 前端开发
常见的JS面试题
【8月更文挑战第5天】 常见的JS面试题
69 3
|
2月前
|
JSON JavaScript 前端开发
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
本文介绍了JSONP的工作原理及其在解决跨域请求中的应用。首先解释了同源策略的概念,然后通过多个示例详细阐述了JSONP如何通过动态解释服务端返回的JavaScript脚本来实现跨域数据交互。文章还探讨了使用jQuery的`$.ajax`方法封装JSONP请求的方式,并提供了具体的代码示例。最后,通过一个更复杂的示例展示了如何处理JSON格式的响应数据。
43 2
[JS]面试官:你的简历上写着熟悉jsonp,那你说说它的底层逻辑是怎样的?
|
5月前
|
存储 JavaScript 前端开发
2022年前端js面试题
2022年前端js面试题
121 57
|
3月前
|
Web App开发 JavaScript 前端开发
前端Node.js面试题
前端Node.js面试题
|
5月前
|
JavaScript 前端开发 程序员
JS小白请看!一招让你的面试成功率大大提高——规范代码
JS小白请看!一招让你的面试成功率大大提高——规范代码
|
5月前
|
JavaScript 前端开发 UED
小白请看! 大厂面试题 :如何用JS实现瀑布流
小白请看! 大厂面试题 :如何用JS实现瀑布流
|
5月前
|
存储 JavaScript 前端开发
JS浅拷贝及面试时手写源码
JS浅拷贝及面试时手写源码
|
5月前
|
JavaScript 前端开发
JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?
JS:类型转换(四)从底层逻辑让你搞懂经典面试问题 [ ] == ![ ] ?
下一篇
开通oss服务