【面试题】2023年前端最新面试题,JS最新面试题-JS篇

原文见:语雀https://www.yuque.com/deepstates/interview/bkbydt

● js基础
● 现代模式
● 数据类型:
○ 数据类型
■ 基础数据类型
■ 引用数据类型
● 普通对象
● Array 数组
● Funciton(函数/类)
● Error对象
● 数字和日期对象
● 文本处理(正则表达式)
● 结构化数据(json)
● 控制抽象化
● 元编程/反射
○ 数据类型的判断

相关知识点:https://www.yuque.com/webfront/js
js基础
对js的理解?
js是一种基于对象和事件驱动,并具有安全性的脚本语言。

说几条写JavaScript的基本规范?

  1. 不要在同一行声明多个变量。
  2. 请使用 ===/!==来比较true/false或者数值
  3. 使用对象字面量替代new Array这种形式
  4. 不要使用全局函数。
  5. Switch语句必须带有default分支
  6. 函数不应该有时候有返回值,有时候没有返回值。
  7. For循环必须使用大括号
  8. If语句必须使用大括号
  9. for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。

js延迟加载的方式有哪些?
defer和async、动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack。用得最多)、按需异步载入js

js对渲染影响?(数字马力)

现代模式,‘use strict’
javascript 代码中的"use strict";是什么意思 ? 使用它区别是什么?
一、use strict是一种ECMAscript 5 添加的(严格)运行模式,这种模式使得 Javascript 在更严格的条件下运行,
二、区别
● 使JS编码更加规范化的模式,消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为。 默认支持的糟糕特性都会被禁用,比如不能用with,也不能在意外的情况下给全局变量赋值; 全局变量的显示声明,函数必须声明在顶层,不允许在非函数代码块内声明函数,arguments.callee也不允许使用; 消除代码运行的一些不安全之处,保证代码运行的安全,限制函数中的arguments修改,严格模式下的eval函数的行为和非严格模式的也不相同;
● 提高编译器效率,增加运行速度; 为未来新版本的Javascript标准化做铺垫。

数据类型
js变量按照存储方式区分为哪些类型?并描述其特点?你能画一下他们的内存图吗?/基本类型与引用类型区别?(百度)(每日互动)
一、两种类型的区别是:存储位置不同
● 原始数据类型:直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
● 引用数据类型:存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体
二、特点
● 值类型存储在栈中,存储的是值 ,赋值之后原变量的值不改变 。
● 引用类型存储在堆中,存储的是地址 ,赋值之后是把原变量的引用地址赋值给新变量 ,新变量改变,原来的会跟着改变。
三、内存图

基础数据类型
number
如何判断 0.1 + 0.2 与 0.3 相等?
参考
非是 ECMAScript 独有
一、浮点数为什么会有精度损失
● 浮点数的二进制表示:十进制转换成二进制,出现第一次精度丢失。
● 浮点数的存储:数字是以 双精度浮点数 保存的,其中53位用来存储尾数。因此0.1 、0.2在保存下来的时候发生了精度丢失
● 浮点数的运算:尾数运算后舍入处理,导致了第三次精度丢失
二、解决方案
1、设置误差范围值,通常称为“机器密度”。对于JavaScript来说,这个值是2的-52次幂,即Math.pow(2, -52)
if(!Number.EPSILON){
Number.EPSILON = Math.pow(2, -52);
}

function numbersCloseEnoughToEqual(n1, n2){
return Math.abs(n1 - n2) < Number.EPSILON;
}

numbersCloseEnoughToEqual(0.1+0.2, 0.3); //true
2、将两边的参数值变成整数后进行比较:将值扩大为1 + 2 和 3 是否相等。

string
字符串方法/ String对象方法?

null、undefined
null和undefined的区别?

  1. null是一个表示”无”的对象,是只有一个值的特殊类型,转为数值时为0;
    undefined是一个表示”无”的原始值,表示一个空对象引用,转为数值时为NaN。
  2. null 和 undefined 的值相等,但类型不等

undefined的典型用法?

  1. 数据
    a. 变量被声明了,但没有赋值时,就等于undefined。
    b. 对象没有赋值的属性,该属性的值为undefined。
  2. 函数
    a. 调用函数时,应该提供的参数没有提供,该参数等于undefined。
    b. 函数没有返回值时,默认返回undefined。

null的典型用法?

  1. 作为函数的参数,表示该函数的参数不是对象。
  2. 作为对象原型链的终点。

引用数据类型
对象
js中有哪些内置对象? / js中有哪些数据封装类对象?
Object 是 JavaScript 中所有对象的父对象
● 数据封装类对象:Object、Array、Boolean、Number 和 String
● 其他对象:Function、Arguments、Math、Date、RegExp、Error

Object.is() 与原来的比较操作符" ===“、” =="的区别?
● 两等号判等,会在比较时进行类型转换;
● 三等号判等(判断严格),比较时不进行隐式类型转换,(类型不同则会返回false);
● Object.is 在三等号判等的基础上特别处理了 NaN 、-0 和 +0
○ 保证 -0 和 +0 不再相同,
○ Object.is(NaN, NaN) 会返回 true
○ Object.is 应被认为有其特殊的用途,而不能用它认为它比其它的相等对比更宽松或严格。

处理对象
javascript创建对象的几种方式?
一、对象初始化器
var o1 = {name: ‘01’};
二、使用构造器
● 构造函数
var M = function(){this.name=‘o2’};
var o2 = new M();
o2.proto=== M.prototype
// o2的构造函数是M
// o2这个普通函数,是M这个构造函数的实例
● 工厂方式(内置对象)
var o11 = new Object({name: ‘011’});
● 原型方式
● 混合方式
三、Object.create()
var P = {name:‘o3’};
var o3 = Object.create§;
四、使用class关键字

es6创建对象与es5创建对象的区别?(bilibili)
● ES5实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.apply(this))。
● ES6实质上是先创建父类的实例对象this(所以必须先调用父类的super()方法),然后再用子类的构造函数修改this。

深拷贝和浅拷贝,分别举例?

  1. 深拷贝:将对象的各个属性进行递归复制。
    a. for…in
    b. JSON.stringify、JSON.parse
    c. lodash.cloneDeep()
  2. 浅拷贝:将对象的各个属性进行依次复制
    a. for…in
    b. Object.assign()
    c. 拷贝访问器属性本身:Object.defineProperties, Object.getOwnPropertyDescriptos
    d. 拷贝对象及原型链上的所有属性:Object.create

对象深拷贝、浅拷贝区别?(百度)
● 深拷贝递归拷贝目标对象的所有属性
● 浅拷贝只会将对象的各个属性进行依次复制,并不会进行递归复制。

怎么做深拷贝?(百度)(网易)(今日互动)(汇信科技)

数组

数组方法/ Array对象方法?/ 数组主要API (大华)

array数组有哪些方法会改变数组本身?(恒生)
● 添加/删除
○ push()、pop()、shift()、unshift()
○ splice()
● 转换
○ sort()、reverse()

函数/类
内置函数
js中有哪些内置函数?
内置函数:
● eval()方法会对一串字符串形式的JavaScript代码字符求值。
● isFinite()函数判断传入的值是否是有限的数值。如果需要的话,其参数首先被转换为一个数值。
● isNaN()
● parseFloat() 函数解析字符串参数,并返回一个浮点数。
● parseInt()
● encodeURI()
● decodeURI()
● encodeURIComponent()
● decodeURIComponent()
● escape():20201217:已废弃
● unescape():20201217:已废弃


ECMAScript6 怎么写class,为什么会出现class这种东西?
新的 class 写法让对象原型的写法更加清晰、更像面向对象编程的语法

类的声明?
1、es5:构造函数,声明一个类
function Animal() {
this.name = ‘name’;
}

2、es6中的class声明
class Animal2 {
constructor() {
this.name = name;
}
}

生成实例?/ 声明一个类,怎么生成类的实例?
/实例化/
console.log(new Animal(), new Animal2()); // 通过New就可以实例化一个类,如果没有参数,Animal后面的()可以不要

箭头函数
箭头函数为什么不能new?
对于 new 操作实质上是定义一个具有构造函数内置对象的实例,生成对象实例的过程也是通过构造函数给实例绑定this的过程。而箭头函数实质是一个匿名内部类,不含有 prototype、没有自己的 this 指向、不可以使用 arguments。所以不能使用 new

函数绑定
call、apply的共同点与区别?
1、改变了函数运行上下文
2、call()和apply()主要是能扩充函数赖以运行作用域。
两者的作用方式相同,它们的区别在于
● 接收参数的方式不同
○ 对于call()而言,第一个参数this与apply()相同,其他的参数必须直接传给函数,要一个一个的列出来
○ 对于apply()来说,apply()可以接收一个数组或arguments对象。
○ 所以如何选择二者,在于哪种给函数传参数的方式最简单。

说说bind、call、apply 区别??
● call 和 apply 都是为了解决改变 this 的指向。作用都是相同的,只是传参的方式不同。
○ 除了第一个参数外,call 可以接收一个参数列表,apply 只接受一个参数数组。
let a = {
value: 1
}
function getValue(name, age) {
console.log(name)
console.log(age)
console.log(this.value)
}
getValue.call(a, ‘yck’, ‘24’)
getValue.apply(a, [‘yck’, ‘24’])
● bind和其他两个方法作用也是一致的,只是该方法会返回一个函数。并且我们可以通过 bind实现柯里化。

文本处理
RegExp正则表达式

结构化数据
JSON
JSON的了解
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小. 如:{“age”:“12”, “name”:“back”}
1、JSON字符串转换为JSON对象:
var obj = eval(‘(’+ str +‘)’);
var obj = str.parseJSON();
var obj = JSON.parse(str);
2、JSON对象转换为JSON字符串:
var last = obj.toJSONString();
var last = JSON.stringify(obj);

JSON —— 作用、用途、设计结构。

stringify序列化对象时,对象的属性为function、null、undefined时结果是什么?
参考
一、作为属性名
● function:忽略
● null、undefined: 转为字符串
二、作为属性值
● function、undefined: 忽略
● null:值仍为null
JSON.stringify({
a() {
console.log(1)
},
null: ‘h’,
undefined:‘test’,
‘good’: ‘very good’
})

// ‘{“null”:“h”,“undefined”:“test”,“good”:“very good”}’
JSON.stringify({
a() {
console.log(1)
},
‘h’: null,
‘test’: undefined,
‘good’: ‘very good’
})

// ‘{“h”:null,“good”:“very good”}’

控制抽象化
Promises
什么是promise?
Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。

promise常用api
Promise 的常用 API 如下:
● Promise.resolve(value)
类方法,该方法返回一个以 value 值解析后的 Promise 对象
1、如果这个值是个 thenable(即带有 then 方法),返回的 Promise 对象会“跟随”这个 thenable 的对象,采用它的最终状态(指 resolved/rejected/pending/settled)
2、如果传入的 value 本身就是 Promise 对象,则该对象作为 Promise.resolve 方法的返回值返回。
3、其他情况以该值为成功状态返回一个 Promise 对象。
上面是 resolve 方法的解释,传入不同类型的 value 值,返回结果也有区别。这个 API 比较重要,建议大家通过练习一些小例子,并且配合上面的解释来熟悉它。如下几个小例子:
//如果传入的 value 本身就是 Promise 对象,则该对象作为 Promise.resolve 方法的返回值返回。
function fn(resolve){
setTimeout(function(){
resolve(123);
},3000);
}
let p0 = new Promise(fn);
let p1 = Promise.resolve(p0);
// 返回为true,返回的 Promise 即是 入参的 Promise 对象。
console.log(p0 === p1);
传入 thenable 对象,返回 Promise 对象跟随 thenable 对象的最终状态。
ES6 Promises 里提到了 Thenable 这个概念,简单来说它就是一个非常类似 Promise 的东西。最简单的例子就是 jQuery.ajax,它的返回值就是 thenable 对象。但是要谨记,并不是只要实现了 then 方法就一定能作为 Promise 对象来使用。
//如果传入的 value 本身就是 thenable 对象,返回的 promise 对象会跟随 thenable 对象的状态。
let promise = Promise.resolve($.ajax(‘/test/test.json’));// => promise对象
promise.then(function(value){
console.log(value);
});
返回一个状态已变成 resolved 的 Promise 对象。
let p1 = Promise.resolve(123);
//打印p1 可以看到p1是一个状态置为resolved的Promise对象
console.log(p1)

● Promise.reject
类方法,且与 resolve 唯一的不同是,返回的 promise 对象的状态为 rejected。
● Promise.prototype.then
实例方法,为 Promise 注册回调函数,函数形式:fn(vlaue){},value 是上一个任务的返回结果,then 中的函数一定要 return 一个结果或者一个新的 Promise 对象,才可以让之后的then 回调接收。
● Promise.prototype.catch
实例方法,捕获异常,函数形式:fn(err){}, err 是 catch 注册 之前的回调抛出的异常信息。
● Promise.race
类方法,多个 Promise 任务同时执行,返回最先执行结束的 Promise 任务的结果,不管这个 Promise 结果是成功还是失败。 。
● Promise.all
类方法,多个 Promise 任务同时执行。
如果全部成功执行,则以数组的方式返回所有 Promise 任务的执行结果。 如果有一个 Promise 任务 rejected,则只返回 rejected 任务的结果。

为什么Promise的状态一旦变化就无法改变?
Promise有3个状态:pending、fulfilled、reject。
pending是未完成,fulfilled、reject是已完成,分别表示成功和失败。
一个状态从未完成变成完成之后不可能再回到未完成,状态从未完成变成成功之后也不可能再变成失败,同理,未完成变成失败后也不可能再变成成功。

介绍promise,异常捕获?(网易)
● .catch处理promise中的各种error:在reject()调用中的,或者在处理程序(handler)中抛出的(thrown)error。
● unhandledrejection事件处理程序(用于浏览器,以及其他环境的模拟),以跟踪未处理的error并告知用户(可能还有我们的服务器)有关信息,以使我们的应用程序永远不会“死掉”

Promsie 与事件循环
Promise在初始化时,传入的函数是同步执行的,然后注册 then 回调。注册完之后,继续往下执行同步代码,在这之前,then 中回调不会执行。同步代码块执行完毕后,才会在事件循环中检测是否有可用的 promise 回调,如果有,那么执行,如果没有,继续下一个事件循环。

什么是async await?
async/await:是一个用同步思维解决异步问题的方案
● 会自动将常规函数转换成Promise,返回值也是一个Promise对象
● 只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数
● 异步函数内部可以使用await
● await放置在Promise调用之前,await强制后面的代码等待,直到Promise对象resolve,得到resolve的值作为await表达式的运算结果
● await只能在async函数内部调用,用在普通函数里就会报错

promise、async有什么区别?(网易)(每日互动)
● promise是es2015,async是es2017
● 兼容性:Promise即使不支持es6,你依然可以用promise的库或polyfil,而async就很难做到,要实现的成本会高很多
● 错误处理:Promise链式操作,自己catch异常。async则要在函数内catch
● api:Promise有很多并行神器,比如Promise.all、Promise.race等,async无法实现
● Promise是显式的异步,而async/await让你的代码看起来是同步的,你依然需要注意异步

async函数与Generator函数的不同点?
● Generator出现在ES2015中,async出现在ES2017中。async是generator的语法糖
● 执行方式不同:async自带执行器,Generator函数需要使用执行器(next()等方法)
● 语义更好:async表示异步,await表示等待异步结果;Generator函数的(*)和yield语义就没那么直接了
● await后既可以是Promise对象,也可以是原始类型的值;Generator中yield后面只能跟Thunk函数或Promise对象
● 返回值不同:async函数的返回的是Promise对象,Generator 函数返回生成器对象

async、await原理
async / await实现原理?(每日互动)
● aysnc函数的实现原理:就是将Generator函数和自动执行器,包装在一个函数里。async函数返回一个promise对象
● async函数return原理:async函数本质还是Generator函数,是通过不断执行遍历器对象的next方法来执行函数。当遍历器对象遍历完毕,就将最后遍历(return)的值resolve出来传递给成功回调
● async函数自动执行原理:await有2个作用:
○ 和yield一样,可以将函数的执行进行切割和分步
○ 可以将await后面的值转化为promise实例,然后指定它的回调。所以通过将async函数的下一步执行指定为这个promise实例的回调,就可以实现async自动执行。
● await返回值原理
○ Generator函数遍历器的next方法的参数,会作为上一个yield的返回值。而await会指定其后promise的成功回调

async await 如何做到阻塞暂停的?

生成器函数里局部变量是否共用的?如果是共用的,又问原理,前一段函数不是执行完了,为什么局部变量保存下来了

数据类型的判断
js使用typeof能得到的哪些类型?
number, string, boolean, undefined, symbol, (注意没有null)
object, function

如何准确判断一个变量arr是数组类型?
● Array.isArray(arr), // true
● arr instanceof Array, // true
● Object.prototye.toString.call(arr),// [object Array]

如何判断一个对象是否属于某一类?/ 判断数据类型的方法有哪些?
typeof、instanceof、constructor、Array.isArray()、Object.prototype.toString.call()

instanceof 可以判断基本类型吗?
不可以

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值