「本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!」
本来今天上午可以更新完成所有面试题,但是上午实在是太忙,一直到现在才有时间,还请大家见谅
14万字 | 400 多道 JavaScript 面试题 🎓 有答案 🌠(第一部分 1-100题)
14万字 | 400 多道 JavaScript 面试题 🎓 有答案 🌠(第二部分 101-200题)
14万字 | 400 多道 JavaScript 面试题 🎓 有答案 🌠(第三部分 201-300题)
14万字 | 400 多道 JavaScript 面试题 🎓 有答案 🌠(第四部分 301-370题)
14万字 | 400 多道 JavaScript 面试题 🎓 有答案 🌠(第五部分 371-424题)
371.是否可以在控制台中调试 HTML 元素?
是的,可以像检查元素一样在控制台中获取和调试 HTML 元素。
const element = document.getElementsByTagName("body")[0];
console.log(element);
它在控制台中打印 HTML 元素,
372.如何使用控制台对象以表格格式显示数据?
所述console.table()用于以表格形式显示在控制台的数据可视化复杂的数组或对象。
const users = [{ "name":"Haiyong", "id": 1, "city": "Beijing"}, { "name":"Max", "id": 2, "city": "London"}, { "name":"CSDN", "id": 3, "city": "Paris"} ];
console.table(users);
以表格形式可视化的数据,
==注意==:请记住,
console.table()
IE 不支持。
373.你如何验证参数是否为数字?
IsNaN 和 isFinite 方法的组合用于确认参数是否为数字。
function isNumber(n){
return !isNaN(parseFloat(n)) && isFinite(n);
}
374.你如何创建复制到剪贴板按钮?
您需要选择输入元素的内容(使用 .select() 方法)并使用 execCommand 执行复制命令(即 execCommand('copy'))。您还可以执行其他系统命令,如剪切和粘贴。
document.querySelector("#copy-button").onclick = function() {
// 选择内容
document.querySelector("#copy-input").select();
// 复制到剪贴板
document.execCommand('copy');
};
375.获取时间戳的快捷方式是什么?
您可以使用new Date().getTime()
来获取当前时间戳。有一个替代的快捷方式来获取值。
console.log(+new Date());
console.log(Date.now());
376.你如何展平多维数组?
使用 Spread 运算符展平二维数组是微不足道的。
const biDimensionalArr = [11, [22, 33], [44, 55], [66, 77], 88, 99];
const flattenArr = [].concat(...biDimensionalArr); // [11, 22, 33, 44, 55,
但是您可以通过递归调用使其适用于多维数组,
function flattenMultiArray(arr) {
const flattened = [].concat(...arr);
return flattened.some(item => Array.isArray(item)) ? flattenMultiArray(flattened) : flattened;
}
const multiDimensionalArr = [11, [22, 33], [44, [55, 66, [77, [88]], 99]]];
const flatArr = flattenMultiArray(multiDimensionalArr); // [11, 22, 33, 44, 55, 66, 77, 88, 99]
377.什么是最简单的多条件检查?
您可以使用indexOf将输入与多个值进行比较,而不是将每个值都作为一个条件进行检查。
// Verbose approach
if (input === 'first' || input === 1 || input === 'second' || input === 2) {
someFunction();
}
// Shortcut
if (['first', 1, 'second', 2].indexOf(input) !== -1) {
someFunction();
}
378.你如何捕获浏览器后退按钮?
该window.onbeforeunload方法用于捕获浏览器后退按钮事件。这有助于警告用户丢失当前数据。
window.onbeforeunload = function() {
alert("You work will be lost");
};
379.如何禁用网页中的右键单击?
可以通过从oncontextmenubody 元素上的属性返回 false 来禁用页面上的右键单击。
<body oncontextmenu="return false;">
380.什么是包装对象?
像字符串、数字和布尔值这样的原始值没有属性和方法,但是当您尝试对它们执行操作时,它们会被临时转换或强制转换为对象(包装对象)。例如,如果对原始字符串值应用 toUpperCase() 方法,它不会抛出错误而是返回字符串的大写。
let name = "csdn";
console.log(name.toUpperCase()); // 在后台处理为 console.log(new String(name).toUpperCase());
即,除 null 和 undefined 之外的每个原语都有包装对象,包装对象列表是 String、Number、Boolean、Symbol 和 BigInt。
381.什么是 AJAX?
AJAX 代表 Asynchronous JavaScript and XML,它是一组用于异步显示数据的相关技术(HTML、CSS、JavaScript、XMLHttpRequest API 等)。即我们可以在不重新加载网页的情况下向服务器发送数据并从服务器获取数据。
382.处理异步代码的不同方式有哪些?
下面是处理异步代码的不同方法的列表。
1.回调 2.承诺 3.异步/等待 4.第三方库,如 async.js、bluebird 等
383.如何取消提取请求?
直到几天前,原生 promise 的一个缺点是无法直接取消 fetch 请求。但是新AbortController的 js 规范允许您使用信号来中止一个或多个 fetch 调用。
取消获取请求的基本流程如下,
1.创建AbortController实例 2.获取实例的信号属性并将信号作为信号的获取选项传递 3.调用 AbortController 的 abort 属性来取消所有使用该信号的获取 例如,让我们将相同的信号传递给多个 fetch 调用将取消所有使用该信号的请求,
const controller = new AbortController();
const { signal } = controller;
fetch("http://localhost:8000", { signal }).then(response => {
console.log(`Request 1 is complete!`);
}).catch(e => {
if(e.name === "AbortError") {
// 我们知道它已被取消!
}
});
fetch("http://localhost:8000", { signal }).then(response => {
console.log(`Request 2 is complete!`);
}).catch(e => {
if(e.name === "AbortError") {
// 我们知道它已被取消!
}
});
// 等待 2 秒以中止两个请求
setTimeout(() => controller.abort(), 2000);
384.什么是网络语音API?
Web 语音 API 用于使现代浏览器能够识别和合成语音(即,将语音数据转换为 Web 应用程序)。该 API 由 W3C 社区于 2012 年引入。它有两个主要部分,
SpeechRecognition(异步语音识别或 Speech-to-Text):它提供了从音频输入中识别语音上下文并做出相应响应的能力。这是通过SpeechRecognition接口访问的。下面的例子展示了如何使用这个 API 从语音中获取文本,
window.SpeechRecognition = window.webkitSpeechRecognition || window.SpeechRecognition; // webkitSpeechRecognition for Chrome and SpeechRecognition for FF
const recognition = new window.SpeechRecognition();
recognition.onresult = (event) => { // SpeechRecognitionEvent type
const speechToText = event.results[0][0].transcript;
console.log(speechToText);
}
recognition.start();
在此 API 中,浏览器将要求您授予使用麦克风的权限
SpeechSynthesis(文本到语音):它提供了从音频输入中识别语音上下文并做出响应的能力。这是通过SpeechSynthesis接口访问的。例如,下面的代码用于从文本中获取语音/语音,
if('speechSynthesis' in window){
var speech = new SpeechSynthesisUtterance('Hello World!');
speech.lang = 'en-US';
window.speechSynthesis.speak(speech);
}
上面的例子可以在 chrome(33+) 浏览器的开发者控制台上进行测试。
==注意==: 这个 API 仍然是一个工作草案,只在 Chrome 和 Firefox 浏览器中可用(当然 Chrome 只实现了规范)
385.什么是最小超时限制?
浏览器和 NodeJS javascript 环境都会以大于 0 毫秒的最小延迟进行节流。这意味着即使设置 0 毫秒的延迟也不会立即发生。
浏览器:它们的最小延迟为 4 毫秒。当由于回调嵌套(特定深度)或在一定数量的连续间隔后触发连续调用时,会发生此限制。
==注意==:旧版浏览器的最小延迟为 10 毫秒。
Nodejs:它们的最小延迟为 1 毫秒。当延迟大于 2147483647 或小于 1 时会发生 此限制。解释此超时限制行为的最佳示例是以下代码片段的顺序。
function runMeFirst() {
console.log('My script is initialized');
}
setTimeout(runMeFirst, 0);
console.log('Script loaded');
并且输出将在
Script loaded
My script is initialized
如果不使用setTimeout,日志的顺序将是顺序的。
function runMeFirst() {
console.log('My script is initialized');
}
runMeFirst();
console.log('Script loaded');
输出是,
My script is initialized
Script loaded
386.你如何在现代浏览器中实现零超时?
由于大于 0ms 的最小延迟,您不能使用 setTimeout(fn, 0) 立即执行代码。但是您可以使用 window.postMessage() 来实现此行为。
387.事件循环中的任务是什么?
任务是任何 javascript 代码/程序,它被安排通过标准机制运行,例如最初开始运行程序、运行事件回调或触发间隔或超时。所有这些任务都安排在一个任务队列中。
以下是将任务添加到任务队列的用例列表,
1.当一个新的 javascript 程序直接从控制台执行或由 <script>
元素运行时,该任务将被添加到任务队列中。
2.当事件触发时,事件回调添加到任务队列
3.当达到 setTimeout 或 setInterval 时,将相应的回调添加到任务队列中
388.什么是微任务?
微任务是需要在当前正在执行的任务/微任务完成后立即执行的 javascript 代码。它们本质上是一种阻塞。即,主线程将被阻塞,直到微任务队列为空。
微任务的主要来源是 Promise.resolve、Promise.reject、MutationObservers、IntersectionObservers 等
==注意==:所有这些微任务都在事件循环的同一轮中处理。
389.什么是不同的事件循环?
390.queueMicrotask 的目的是什么?
391.你如何在 typescript 文件中使用 javascript 库?
众所周知,并非所有 JavaScript 库或框架都有 TypeScript 声明文件。但是如果你仍然想在我们的 TypeScript 文件中使用库或框架而不会出现编译错误,唯一的解决方案是declare
关键字和变量声明。例如,假设您有一个名为的库customLibrary
,它没有 TypeScript 声明,并且customLibrary
在全局命名空间中调用了一个命名空间。您可以在打字稿代码中使用这个库,如下所示,
declare var customLibrary;
在运行时,typescript 会将类型customLibrary
作为any
类型提供给变量。不使用声明关键字的另一种选择如下
var customLibrary: any;
392.promises 和 observables 有什么区别?
表格形式的一些主要区别
promises | observables |
---|---|
一次只发出一个值 | 在一段时间内发出多个值(从 0 到多个的值流) |
天生渴望;他们将被立即调用 | 天性懒惰;他们需要调用订阅 |
Promise 总是异步的,即使它立即解决了 | Observable 可以是同步的也可以是异步的 |
不提供任何操作符 | 提供map、forEach、filter、reduce、retry、retryWhen等操作符 |
不能取消 | 使用 unsubscribe() 方法取消 |
393.什么是堆?
堆(或内存堆)是我们定义变量时存放对象的内存位置。即,这是所有内存分配和取消分配发生的地方。堆和调用栈都是 JS 运行时的两个容器。
每当运行时遇到代码中的变量和函数声明时,它都会将它们存储在堆中。
394.什么是事件表?
事件表是一种 数据结构,用于存储和跟踪将在一段时间间隔后或在某些 API 请求解析后异步执行的所有事件。即,每当您调用 setTimeout 函数或调用异步操作时,它都会被添加到事件表中。
它不会自行执行功能。事件表的主要目的是跟踪事件并将它们发送到事件队列,如下图所示。
395.什么是微任务队列?
Microtask Queue 是一个新的队列,所有由 promise 对象发起的任务都在回调队列之前得到处理。
微任务队列在下一个渲染和绘制作业之前处理。但是,如果这些微任务运行很长时间,则会导致视觉质量下降。
396.shim 和 polyfill 有什么区别?
shim 是一个库,它为旧环境带来新的 API,仅使用该环境的手段。它不一定限于 Web 应用程序。例如,es5-shim.js 用于在旧浏览器(主要是 IE9 之前)上模拟 ES5 功能。
而 polyfill 是一段代码(或插件),它提供您(开发人员)希望浏览器本地提供的技术。
简单来说,polyfill 是浏览器 API 的垫片。
397.你如何检测原始或非原始值类型?
在 JavaScript 中,原始类型包括 boolean、string、number、BigInt、null、Symbol 和 undefined。而非原始类型包括对象。但是您可以使用以下功能轻松识别它们,
var myPrimitive = 30;
var myNonPrimitive = {};
function isPrimitive(val) {
return Object(val) !== val;
}
isPrimitive(myPrimitive);
isPrimitive(myNonPrimitive);
如果该值是原始数据类型,则 Object 构造函数为该值创建一个新的包装器对象。但是如果该值是非原始数据类型(一个对象),则 Object 构造函数将给出相同的对象。
398.什么是Babel ?
Babel 是一个 JavaScript 转译器,用于在当前和旧浏览器或环境中将 ECMAScript 2015+ 代码转换为向后兼容的 JavaScript 版本。下面列出了一些主要功能,
1.转换语法 2.目标环境中缺少的 Polyfill 功能(使用@babel / polyfill) 3.源代码转换(或 codemods)
399.Node.js 是完全单线程的吗?
Node 是单线程的,但是 Node.js 标准库中包含的一些函数(例如 fs 模块函数)不是单线程的。即,它们的逻辑在 Node.js 单线程之外运行,以提高程序的速度和性能。
400.可观察对象的常见用例是什么?
一些最常见的 observable 用例是带有推送通知、用户输入更改、重复间隔等的网络套接字
401.什么是 RxJS?
RxJS (Reactive Extensions for JavaScript) 是一个使用 observables 实现反应式编程的库,它可以更容易地编写异步或基于回调的代码。它还提供了用于创建和使用 observable 的实用函数。
402.函数构造函数和函数声明有什么区别?
创建的函数Function constructor不会为其创建上下文创建闭包,但它们始终在全局范围内创建。即,函数只能访问它自己的局部变量和全局范围变量。而函数声明也可以访问外部函数变量(闭包)。
让我们通过一个例子来看看这种差异,
函数构造器:
var a = 100;
function createFunction() {
var a = 200;
return new Function('return a;');
}
console.log(createFunction()()); // 100
函数声明:
var a = 100;
function createFunction() {
var a = 200;
return function func() {
return a;
}
}
console.log(createFunction()()); // 200
403.什么是短路状态?
短路条件适用于编写简单 if 语句的精简方式。让我们用一个例子来演示这个场景。如果您想登录带有身份验证条件的门户,则表达式如下,
if (authenticate) {
loginToPorta();
}
由于 javascript 逻辑运算符从左到右计算,因此可以使用 && 逻辑运算符简化上述表达式
authenticate && loginToPorta();
404.调整数组大小的最简单方法是什么?
数组的长度属性可用于快速调整数组大小或清空数组。让我们在数字数组上应用 length 属性以将元素数量从 5 调整为 2,
var array = [1, 2, 3, 4, 5];
console.log(array.length); // 5
array.length = 2;
console.log(array.length); // 2
console.log(array); // [1,2]
数组也可以清空
var array = [1, 2, 3, 4, 5];
array.length = 0;
console.log(array.length); // 0
console.log(array); // []
405.什么是可观察的?
Observable 基本上是一个函数,它可以随着时间的推移同步或异步地将值流返回给观察者。消费者可以通过调用subscribe()方法获取值。
让我们看一个 Observable 的简单例子
import { Observable } from 'rxjs';
const observable = new Observable(observer => {
setTimeout(() => {
observer.next('Message from a Observable!');
}, 3000);
});
observable.subscribe(value => console.log(value));
注意: Observable 还不是 JavaScript 语言的一部分,但建议将它们添加到语言中
406.函数声明和类声明有什么区别?
函数声明和类声明之间的主要区别是hoisting. 函数声明被提升,但不是类声明。
Classes:
const user = new User(); // ReferenceError
class User {}
构造函数:
const user = new User(); // No error
function User() {
}
407.什么是异步函数?
异步函数是一个用async关键字声明的函数,它可以通过避免承诺链以更简洁的风格编写异步的、基于承诺的行为。这些函数可以包含零个或多个await表达式。
让我们看一个下面的异步函数示例,
async function logger() {
let data = await fetch('http://someapi.com/users'); // 暂停直到 fetch 返回
console.log(data)
}
logger();
它基本上是 ES2015 承诺和生成器的语法糖。
408.你如何防止 promises swallowing errors?
在使用异步代码时,JavaScript 的 ES6 承诺可以让您的生活变得更轻松,而无需每两行都有回调金字塔和错误处理。但是 Promises 有一些陷阱,最大的一个是默认吞下错误。
假设您希望在以下所有情况下向控制台打印错误,
Promise.resolve('promised value').then(function() {
throw new Error('error');
});
Promise.reject('error value').catch(function() {
throw new Error('error');
});
new Promise(function(resolve, reject) {
throw new Error('error');
});
但是有许多现代 JavaScript 环境不会打印任何错误。你可以用不同的方式解决这个问题,
1.在每个链的末尾添加 catch 块:您可以在每个承诺链的末尾添加 catch 块
Promise.resolve('promised value').then(function() {
throw new Error('error');
}).catch(function(error) {
console.error(error.stack);
});
但是很难为每个承诺链打字,而且也很冗长。
2.添加完成方法:您可以用完成方法替换第一个解决方案的 then 和 catch 块
Promise.resolve('promised value').done(function() {
throw new Error('error');
});
假设您想使用 HTTP 获取数据,然后异步处理结果数据。您可以编写done如下块,
getDataFromHttp()
.then(function(result) {
return processDataAsync(result);
})
.done(function(processed) {
displayData(processed);
});
将来,如果处理库 API 更改为同步,则可以删除done块,如下所示,
getDataFromHttp()
.then(function(result) {
return displayData(processDataAsync(result));
})
然后您忘记添加done块到then块会导致无提示错误。
3.通过 Bluebird 扩展 ES6 Promises: Bluebird 扩展了 ES6 Promises API 以避免第二个解决方案中的问题。这个库有一个“默认”的 onRejection 处理程序,它将把所有错误从被拒绝的 Promise 打印到 stderr。安装后,您可以处理未处理的拒绝
Promise.onPossiblyUnhandledRejection(function(error){
throw error;
});
并丢弃拒绝,只需用空捕获处理它
Promise.reject('error value').catch(function() {});
409.什么是 deno ?
Deno 是一个简单、现代且安全的 JavaScript 和 TypeScript 运行时,它使用 V8 JavaScript 引擎和 Rust 编程语言。
410.你如何在javascript中使对象可迭代?
默认情况下,普通对象不可迭代。但是您可以通过Symbol.iterator在其上定义属性来使对象可迭代。
让我们用一个例子来证明这一点,
const collection = {
one: 1,
two: 2,
three: 3,
[Symbol.iterator]() {
const values = Object.keys(this);
let i = 0;
return {
next: () => {
return {
value: this[values[i++]],
done: i > values.length
}
}
};
}
};
const iterator = collection[Symbol.iterator]();
console.log(iterator.next()); // → {value: 1, done: false}
console.log(iterator.next()); // → {value: 2, done: false}
console.log(iterator.next()); // → {value: 3, done: false}
console.log(iterator.next()); // → {value: undefined, done: true}
可以使用生成器函数简化上述过程,
const collection = {
one: 1,
two: 2,
three: 3,
[Symbol.iterator]: function * () {
for (let key in this) {
yield this[key];
}
}
};
const iterator = collection[Symbol.iterator]();
console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
411.什么是正确的尾调用?
首先,在谈论“正确的尾调用”之前,我们应该先了解尾调用。尾调用是作为调用函数的最终动作执行的子例程或函数调用。而适当的尾调用 (PTC)是一种技术,当函数调用是尾调用时,程序或代码不会为递归创建额外的堆栈帧。
例如,下面的经典或阶乘函数的头递归依赖于每个步骤的堆栈。每一步都需要处理到n * factorial(n - 1)
function factorial(n) {
if (n === 0) {
return 1
}
return n * factorial(n - 1)
}
console.log(factorial(5)); //120
但是,如果您使用尾递归函数,它们会在不依赖堆栈的情况下继续将所需的所有数据传递到递归中。
function factorial(n, acc = 1) {
if (n === 0) {
return acc
}
return factorial(n - 1, n * acc)
}
console.log(factorial(5)); //120
上述模式返回与第一个相同的输出。但是累加器将 total 作为参数进行跟踪,而无需在递归调用中使用堆栈内存。
412.你如何检查一个对象是否是一个承诺?
如果你不知道一个值是否是一个承诺,包装该值作为Promise.resolve(value)它返回一个承诺
function isPromise(object){
if(Promise && Promise.resolve){
return Promise.resolve(object) == object;
}else{
throw "Promise not supported in your environment"
}
}
var i = 1;
var promise = new Promise(function(resolve,reject){
resolve()
});
console.log(isPromise(i)); // false
console.log(isPromise(p)); // true
另一种方法是检查.then()处理程序类型
function isPromise(value) {
return Boolean(value && typeof value.then === 'function');
}
var i = 1;
var promise = new Promise(function(resolve,reject){
resolve()
});
console.log(isPromise(i)) // false
console.log(isPromise(promise)); // true
413.如何检测函数是否被调用为构造函数?
您可以使用new.target伪属性来检测函数是作为构造函数(使用 new 运算符)还是作为常规函数调用调用的。
如果使用 new 运算符调用构造函数或函数,则 new.target 返回对构造函数或函数的引用。 对于函数调用,new.target 是未定义的。
function Myfunc() {
if (new.target) {
console.log('called with new');
} else {
console.log('not called with new');
}
}
new Myfunc(); // called with new
Myfunc(); // not called with new
Myfunc.call({}); not called with new
414.arguments 对象和rest 参数之间有什么区别?
arguments 对象和 rest 参数之间有三个主要区别
1.arguments 对象是一个类似数组的对象,但不是一个数组。而rest 参数是数组实例。 2.arguments 对象不支持 sort、map、forEach 或 pop 等方法。而这些方法可用于rest 参数。 3.rest 参数只是那些没有被赋予单独名称的参数,而参数对象包含传递给函数的所有参数
415.扩展运算符和rest 参数之间有什么区别?
Rest 参数将所有剩余元素收集到一个数组中。而Spread运算符允许将可迭代对象(数组/对象/字符串)扩展为单个参数/元素。即,Rest 参数与扩展运算符相反。
416.有哪些不同种类的 generators(生成器)?
有五种生成器,
1.生成器函数声明:
function* myGenFunc() {
yield 1;
yield 2;
yield 3;
}
const genObj = myGenFunc();
2.生成器函数表达式:
const myGenFunc = function* () {
yield 1;
yield 2;
yield 3;
};
const genObj = myGenFunc();
3.对象字面量中的生成器方法定义:
const myObj = {
* myGeneratorMethod() {
yield 1;
yield 2;
yield 3;
}
};
const genObj = myObj.myGeneratorMethod();
4.class 中的生成器方法定义:
class MyClass {
* myGeneratorMethod() {
yield 1;
yield 2;
yield 3;
}
}
const myObject = new MyClass();
const genObj = myObject.myGeneratorMethod();
5.生成器作为计算属性:
const SomeObj = {
*[Symbol.iterator] () {
yield 1;
yield 2;
yield 3;
}
}
console.log(Array.from(SomeObj)); // [ 1, 2, 3 ]
417.什么是内置可迭代对象?
下面是 javascript 中内置的可迭代对象列表,
1.数组和类型数组 2.字符串:迭代每个字符或 Unicode 代码点 3.Maps:迭代其键值对 4.集合:迭代它们的元素 5.参数:函数中类似数组的特殊变量 6.NodeList 等 DOM 集合
418.for…of 和 for…in 语句之间有什么区别?
for...in 和 for...of 语句都遍历 js 数据结构。唯一的区别在于它们迭代的内容:
for..in 迭代对象的所有可枚举属性键 for..of 迭代可迭代对象的值。 让我们用一个例子来解释这种差异,
let arr = ['a', 'b', 'c'];
arr.newProp = 'newVlue';
// key 是属性键
for (let key in arr) {
console.log(key);
}
// value 是属性值
for (let value of arr) {
console.log(value);
}
由于 for..in 循环遍历对象的键,第一个循环在遍历数组对象时记录 0、1、2 和 newProp。for..of 循环遍历 arr 数据结构的值并在控制台中记录 a、b、c。
419.如何定义实例和非实例属性?
Instance 属性必须在类方法中定义。例如,名称和年龄属性定义的内部构造函数如下,
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
但是必须在 ClassBody 声明之外定义 Static(class) 和原型数据属性。让我们为 Person 类分配年龄值,如下所示,
Person.staticAge = 30;
Person.prototype.prototypeAge = 40;
420.isNaN 和 Number.isNaN 有什么区别?
1.isNaN:全局函数isNaN将参数转换为数字,如果结果值为 NaN,则返回 true。 2.Number.isNaN:此方法不转换参数。但当类型为 Number 且值为 NaN 时,它返回 true。 让我们通过一个例子来看看区别,
isNaN(‘hello’); // true
Number.isNaN('hello'); // false
421.如何在没有任何额外括号的情况下调用 IIFE?
立即调用函数表达式(IIFE)需要一对括号来包装包含语句集的函数。
(function(dt) {
console.log(dt.toLocaleTimeString());
})(new Date());
由于 IIFE 和 void 运算符都会丢弃表达式的结果,因此您可以避免使用void operatorfor IIFE的额外括号,如下所示,
void function(dt) {
console.log(dt.toLocaleTimeString());
}(new Date());
422.可以在 switch case 中使用表达式吗?
您可能已经看到在 switch 条件中使用的表达式,但也可以通过为 switch 条件分配真值来用于 switch case。让我们以基于温度的天气状况为例,
const weather = function getWeather(temp) {
switch(true) {
case temp < 0: return 'freezing';
case temp < 10: return 'cold';
case temp < 24: return 'cool';
default: return 'unknown';
}
}(10);
423.忽略promise 错误的最简单方法是什么?
忽略promise 错误的最简单和最安全的方法是使该错误无效。这种方法也是 ESLint 友好的。
await promise.catch(e => void e);
424.如何使用 CSS 设置控制台输出的样式?
您可以使用 CSS 格式内容说明符 %c 将 CSS 样式添加到控制台输出。控制台字符串消息可以附加在另一个参数中的说明符和 CSS 样式之后。让我们使用 console.log 和 CSS 说明符打印红色文本,如下所示,
console.log("%cThis is a red text", "color:red");
还可以为内容添加更多样式。比如上面的文字可以修改font-size
console.log("%cThis is a red text with bigger font", "color:red; font-size
我已经写了很长一段时间的技术博客,这是我的一篇面试题文章。希望你们会喜欢!
更多相关文章及我的联系方式我放在这里:
github.com/wanghao221
gitee.com/haiyongcsdn…
如果你真的从这篇文章中学到了一些新东西,喜欢它,收藏它并与你的小伙伴分享。🤗最后,不要忘了❤或📑支持一下哦