这是我参与更文挑战的第27天,活动详情查看: 更文挑战
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题)
为了方便手机阅览,我在必要位置都放了回顶部或者回对应问题的链接
1.在 JavaScript 中创建对象的可行方法有哪些?
有很多方法可以在 javascript 中创建对象,如下所示
1.对象构造函数:
创建空对象的最简单方法是使用 Object 构造函数。目前不推荐这种方法。
var object = new Object();
2.对象的创建方法:
Object 的 create 方法通过将原型对象作为参数传递来创建一个新对象
var object = Object.create(null);
3.对象字面量语法:
当传递 null 作为参数时,对象字面量语法等效于 create 方法
var object = {};
4.函数构造器:
创建任何函数并应用 new 运算符来创建对象实例,
function Person(name){
var object = {};
object.name=name;
object.age=21;
return object;
}
var object = new Person("Sudheer");
5.带有原型的函数构造函数:
这类似于函数构造函数,但它使用原型作为其属性和方法,
function Person(){}
Person.prototype.name = "Sudheer";
var object = new Person();
这等效于使用具有函数原型的对象创建方法创建的实例,然后使用实例和参数作为参数调用该函数。
function func {};
new func(x, y, z);
(或者)
// 使用函数原型创建一个新实例。
var newInstance = Object.create(func.prototype)
// 调用函数
var result = func.call(newInstance, x, y, z),
// 如果结果是非空对象,则使用它,否则只使用新实例。
console.log(result && typeof result === 'object' ? result : newInstance);
6.ES6 类语法:
ES6 引入类特性来创建对象
class Person {
constructor(name) {
this.name = name;
}
}
var object = new Person("Sudheer");
7.单例模式:
Singleton 是一个只能实例化一次的对象。对其构造函数的重复调用返回相同的实例,这样可以确保它们不会意外创建多个实例。
var object = new function(){
this.name = "Sudheer";
}
2.什么是原型链?
原型链用于基于现有对象构建新类型的对象。它类似于基于类的语言中的继承。
对象实例上的原型可通过Object.getPrototypeOf(object)或proto属性获得,而构造函数上的原型可通过Object.prototype 获得。
3.call、apply、bind有什么区别?
Call、Apply 和 Bind 之间的区别可以用下面的例子来解释,
call: call() 方法调用一个函数,给定的this值和参数一一提供
var employee1 = {firstName: 'Haiyong', lastName: 'Rodson'};
var employee2 = {firstName: 'Jimmy', lastName: 'Baily'};
function invite(greeting1, greeting2) {
console.log(greeting1 + ' ' + this.firstName + ' ' + this.lastName+ ', '+ greeting2);
}
invite.call(employee1, 'Hello', 'How are you?'); // Hello Haiyong Rodson, How are you?
invite.call(employee2, 'Hello', 'How are you?'); // Hello Jimmy Baily, How are you?
apply:调用具有给定this值的函数,并允许你将参数作为数组传入
var employee1 = {firstName: 'Haiyong', lastName: 'Rodson'};
var employee2 = {firstName: 'Jimmy', lastName: 'Baily'};
function invite(greeting1, greeting2) {
console.log(greeting1 + ' ' + this.firstName + ' ' + this.lastName+ ', '+ greeting2);
}
invite.apply(employee1, ['Hello', 'How are you?']); // Hello Haiyong Rodson, How are you?
invite.apply(employee2, ['Hello', 'How are you?']); // Hello Jimmy Baily, How are you?
bind:返回一个新函数,允许你传递任意数量的参数
var employee1 = {firstName: 'Haiyong', lastName: 'Rodson'};
var employee2 = {firstName: 'Jimmy', lastName: 'Baily'};
function invite(greeting1, greeting2) {
console.log(greeting1 + ' ' + this.firstName + ' ' + this.lastName+ ', '+ greeting2);
}
var inviteEmployee1 = invite.bind(employee1);
var inviteEmployee2 = invite.bind(employee2);
inviteEmployee1('Hello', 'How are you?'); // Hello Haiyong Rodson, How are you?
inviteEmployee2('Hello', 'How are you?'); // Hello Jimmy Baily, How are you?
Call 和 apply 可以互换。两者都立即执行当前函数。你需要决定是发送数组还是逗号分隔的参数列表更容易。你可以通过处理 Call 用于逗号(分隔列表)和 Apply 用于Array来记住。
而 Bind 创建一个新函数,该函数将this设置为传递给 bind() 的第一个参数。
4.什么是 JSON 及其常见操作?
JSON是一种基于文本的数据格式,遵循 JavaScript 对象语法,由道格拉斯·克罗克福德 (Douglas Crockford) 推行。 当你想通过网络传输数据时它很有用,它基本上只是一个扩展名为 .json 的文本文件,以及一个 MIME 类型的 application/json
解析:将字符串转换为原生对象
JSON.parse(text)
字符串化:将本机对象转换为字符串,以便可以通过网络传输
JSON.stringify(object)
5. 数组slice()方法的目的是什么?
所述slice()方法返回在数组作为新的数组对象中选定的元件。它选择从给定开始参数开始的元素,并在给定的可选结束参数处结束,不包括最后一个元素。如果省略第二个参数,则它会一直选择到最后。
这种方法的一些例子是,
let arrayIntegers = [1, 2, 3, 4, 5];
let arrayIntegers1 = arrayIntegers.slice(0,2); // returns [1,2]
let arrayIntegers2 = arrayIntegers.slice(2,3); // returns [3]
let arrayIntegers3 = arrayIntegers.slice(4); //returns [5]
==注意==: Slice 方法不会改变原始数组,而是将子集作为新数组返回。
6.数组splice()方法的目的是什么?
splice() 方法用于向/从数组添加/删除项目,然后返回被删除的项目。第一个参数指定插入或删除的数组位置,而选项第二个参数指示要删除的元素数。每个附加参数都添加到数组中。
这种方法的一些例子是,
let arrayIntegersOriginal1 = [1, 2, 3, 4, 5];
let arrayIntegersOriginal2 = [1, 2, 3, 4, 5];
let arrayIntegersOriginal3 = [1, 2, 3, 4, 5];
let arrayIntegers1 = arrayIntegersOriginal1.splice(0,2); // returns [1, 2]; original array: [3, 4, 5]
let arrayIntegers2 = arrayIntegersOriginal2.splice(3); // returns [4, 5]; original array: [1, 2, 3]
let arrayIntegers3 = arrayIntegersOriginal3.splice(3, 1, "a", "b", "c"); //returns [4]; original array: [1, 2, 3, "a", "b", "c", 5]
==注意==: Splice 方法修改原始数组并返回删除的数组。
7.slice()和splice()有什么区别?
表格形式的一些主要区别
| slice() | splice() |
|---|---|
| 不修改原始数组(不可变) | 修改原始数组(可变) |
| 返回原始数组的子集 | 将删除的元素作为数组返回 |
| 用于从数组中选取元素 | 用于在数组中插入或删除元素 |
8.你如何比较 Object 和 Map
Object 与Maps 的相似之处在于,它们都允许您将键设置为值、检索这些值、删除键以及检测某个键是否存储了某些内容。由于这个原因,对象在历史上被用作地图。但是在某些情况下,使用 Map 有一些重要的区别。
- Object 的键是字符串和符号,而它们可以是 Map 的任何值,包括functions、Object 和任何primitive。
- Map 中的键是有序的,而添加到 Object 的键不是。因此,当迭代它时,一个 Map 对象按插入的顺序返回键。
- 您可以使用 size 属性轻松获取 Map 的大小,而 Object 中的属性数量必须手动确定。
- Map 是可迭代的,因此可以直接迭代,而迭代 Object 需要以某种方式获取其键并对其进行迭代。
- 一个对象有一个原型,所以如果你不小心,地图中有一些默认的键可能会与你的键发生冲突。从 ES5 开始,这可以通过使用
map =Object.create(null)绕过,但很少这样做。 - Map在涉及频繁添加和删除密钥对的场景中可能表现得更好。
9.== 和 === 运算符有什么区别?
JavaScript 提供了严格(===, !==) 和类型转换(==, !=) 相等比较。严格运算符考虑变量的类型,而非严格运算符根据变量的值进行类型校正/转换。严格的运算符遵循以下不同类型的条件,
- 当两个字符串具有相同的字符序列、相同的长度以及相应位置的相同字符时,它们是严格相等的。
- 当两个数字在数值上相等时,它们严格相等。即,具有相同的数值。这里有两种特殊情况,
NaN 不等于任何东西,包括 NaN。
正零和负零彼此相等。
- 如果两个布尔操作数都为真或都为假,则两个布尔操作数严格相等。
- 如果两个对象引用同一个对象,则它们严格相等。
- Null 和 Undefined 类型与
===不相等,但与==相等。即,null===undefined --> false但null==undefined --> true一些涵盖上述情况的例子,
0 == false // true
0 === false // false
1 == "1" // true
1 === "1" // false
null == undefined // true
null === undefined // false
'0' == false // true
'0' === false // false
[]==[] or []===[] //false, refer different objects in memory
{}=={} or {}==={} //false, refer different objects in memory
10.什么是 lambda 或 箭头函数?
箭头函数是函数表达式的较短语法,没有自己的this、arguments、super 或 new.target。这些函数最适合非方法函数,它们不能用作构造函数。
11.什么是头等函数?
在 Javascript 中,函数是第一类对象。头等函数意味着该语言中的函数被视为任何其他变量。
例如,在这种语言中,一个函数可以作为参数传递给其他函数,可以由另一个函数返回,也可以作为一个值分配给一个变量。例如,在下面的示例中,分配给侦听器的处理函数
const handler = () => console.log ('This is a click handler function');
document.addEventListener ('click', handler);
12.什么是一阶函数?
一阶函数是不接受另一个函数作为参数并且不返回函数作为其返回值的函数。
const firstOrder = () => console.log ('I am a first order function!');
13.什么是高阶函数?
高阶函数是接受另一个函数作为参数或返回一个函数作为返回值或两者兼而有之的函数。
const firstOrderFunc = () => console.log ('Hello, I am a First order function');
const higherOrder = ReturnFirstOrderFunc => ReturnFirstOrderFunc();
higherOrder(firstOrderFunc);
14.什么是一元函数?
一元函数(即 monadic)是一个只接受一个参数的函数。它代表一个函数接受的单个参数。
让我们以一元函数为例,
const unaryFunction = a => console.log (a + 10); // 给给定的参数加 10
15.什么是柯里化函数?
柯里化是将具有多个参数的函数转换为每个只有一个参数的函数序列的过程。Currying 以数学家Haskell Curry 的名字命名。通过应用柯里化,n 元函数将其变成一元函数。
让我们举一个 n-ary 函数的例子,以及它如何变成一个柯里化函数,
const multiArgFunction = (a, b, c) => a + b + c;
console.log(multiArgFunction(1,2,3));// 6
const curryUnaryFunction = a => b => c => a + b + c;
curryUnaryFunction (1); // return a function: b => c => 1 + b + c
curryUnaryFunction (1) (2); // return a function: c => 3 + c
curryUnaryFunction (1) (2) (3); // return 数字 6
Curried 函数对于提高代码复用性和函数组合非常有用。
16.什么是纯函数?
一个纯函数是在返回值是由它的参数没有任何副作用只有确定的函数。即如果您在应用程序中调用具有相同参数 'n' 次和 'n' 个位置的函数,则它将始终返回相同的值。
我们举个例子来看看纯函数和非纯函数的区别,
//不纯
let numberArray = [];
const impureAddNumber = number => numberArray.push(number);
//纯
const pureAddNumber = number => argNumberArray =>
argNumberArray.concat([number]);
//显示结果
console.log (impureAddNumber(6)); // returns 1
console.log (numberArray); // returns [6]
console.log (pureAddNumber(7) (numberArray)); // returns [6, 7]
console.log (numberArray); // returns [6]
根据上面的代码片段,通过改变数组并返回一个与参数值无关的推送数字索引,推送函数本身是不纯的。而另一方面,Concat获取数组并将其与另一个数组连接起来,产生一个没有副作用的全新数组。此外,返回值是前一个数组的串联。
请记住,纯函数很重要,因为它们简化了单元测试,没有任何副作用,也不需要依赖注入。它们还避免了紧密耦合,并通过没有任何副作用使您的应用程序更难中断。这些原则通过优先使用const 而不是let与 ES6 的不变性概念结合在一起。
17.let 关键字的用途是什么?
let语句声明了一个块作用域局部变量。因此,使用 let 关键字定义的变量的范围仅限于使用它的块、语句或表达式。而使用var关键字声明的变量用于定义全局变量或局部变量,而不管块作用域如何。
我们举个例子来演示一下用法,
let counter = 30;
if (counter === 30) {
let counter = 31;
console.log(counter); // 31
}
console.log(counter); // 30 (因为这里不存在 if 块中的变量)
18.let 和 var 有什么区别?
以表格格式列出差异
| var | let |
|---|---|
| 它从 JavaScript 开始就可用 | 作为 ES6 的一部分引入 |
| 它有函数作用域 | 它有块作用域 |
| 变量将被提升 | 已提升但未初始化 |
| 让我们举个例子看看区别, |
function userDetails(username) {
if(username) {
console.log(salary); // 由于变量提升未定义
console.log(age); // 参考错误:初始化前无法访问"age"
let age = 30;
var salary = 10000;
}
console.log(salary); //10000 (可访问到适当的函数范围)
console.log(age); //error:age未定义(由于块作用域)
}
userDetails('Haiyong');
19. 为什么选择 let 这个名字作为关键字?
let是一种数学语句,被早期的编程语言如Scheme和Basic 所采用。它是从数十种其他语言中借用而来的,这些语言let已经尽可能地作为传统关键字使用var。
20.你如何在没有错误的情况下重新声明 switch 块中的变量?
如果您尝试在 a 中重新声明变量,switch block则会导致错误,因为只有一个块。例如,下面的代码块抛出如下语法错误,
let counter = 1;
switch(x) {
case 0:
let name;
break;
case 1:
let name; // 重新声明的语法错误。
break;
}
为避免此错误,您可以在 case 子句中创建一个嵌套块并创建一个新的块范围词法环境。
let counter = 1;
switch(x) {
case 0: {
let name;
break;
}
case 1: {
let name; // 没有用于重新声明的 SyntaxError。
break;
}
}
21.什么是暂时性死区?
暂时性死区是 JavaScript 中的一种行为,在使用 let 和 const 关键字声明变量时发生,但不使用 var 声明变量。在 ECMAScript 6 中,在其声明之前(在其范围内)访问letorconst变量会导致 ReferenceError。发生这种情况的时间跨度,即变量绑定的创建和声明之间,称为时间死区。
让我们用一个例子来看看这个行为,
function somemethod() {
console.log(counter1); // undefined
console.log(counter2); // ReferenceError
var counter1 = 1;
let counter2 = 2;
}
22.什么是IIFE(立即执行函数表达式)?
IIFE(立即调用函数表达式)是一个 JavaScript 函数,它在定义后立即运行。它的签名如下,
(function ()
{
// 在这里写逻辑
}
)
();
使用 IIFE 的主要原因是为了获得数据隐私,因为在 IIFE 中声明的任何变量都不能被外界访问。即,如果您尝试使用 IIFE 访问变量,则会引发如下错误,
(function ()
{
var message = "IIFE";
console.log(message);
}
)
();
console.log(message); //Error: message is not defined(消息未定义)
23.使用模块有什么好处?
使用模块有利于扩展有很多好处。其中一些好处是,
- 可维护性
- 可重用性
- 命名空间
24.什么是memoization(记忆)?
Memoization 是一种编程技术,它试图通过缓存先前计算的结果来提高函数的性能。每次调用 memoized 函数时,都会使用其参数来索引缓存。如果数据存在,则可以返回它,而无需执行整个函数。否则执行该函数,然后将结果添加到缓存中。
让我们举一个添加记忆化功能的例子,
const memoizAddition = () => {
let cache = {};
return (value) => {
if (value in cache) {
console.log('Fetching from cache');
return cache[value]; // 在这里, cache.value 不能用作以数字开头的属性名称,该数字不是有效的 JavaScript 标识符。 因此,只能使用方括号表示法访问。
}
else {
console.log('Calculating result');
let result = value + 20;
cache[value] = result;
return result;
}
}
}
// memoizAddition 返回的函数
const addition = memoizAddition();
console.log(addition(20)); //输出: 40 calculated
console.log(addition(20)); //输出: 40 cached
25.什么是Hoisting(变量提升)?
Hoisting是一种 JavaScript 机制,其中变量和函数声明在代码执行之前被移动到其作用域的顶部。请记住,JavaScript 只提升声明,而不是初始化。 我们举一个简单的变量提升的例子,
console.log(message); //输出: undefined
var message = 'The variable Has been hoisted';
上面的代码看起来像下面的解释器,
var message;
console.log(message);
message = 'The variable Has been hoisted';
26.ES6 中的类是什么?
在 ES6 中,Javascript 类主要是对 JavaScript 现有的基于原型的继承的语法糖。
例如,在函数表达式中编写的基于原型的继承如下,
function Bike(model,color) {
this.model = model;
this.color = color;
}
Bike.prototype.getDetails = function() {
return this.model + ' bike has' + this.color + ' color';
};
而 ES6 类可以定义为替代
class Bike{
constructor(color, model) {
this.color= color;
this.model= model;
}
getDetails() {
return this.model + ' bike has' + this.color + ' color';
}
}
27.什么是closures(闭包)?
闭包是函数和声明该函数的词法环境的组合。即,它是一个内部函数,可以访问外部或封闭函数的变量。闭包有三个作用域链
- 自己的范围,其中在其大括号之间定义变量
- 外部函数的变量
- 全局变量
让我们举一个闭包概念的例子,
function Welcome(name){
var greetingInfo = function(message){
console.log(message+' '+name);
}
return greetingInfo;
}
var myFunction = Welcome('Haiyong');
myFunction('Welcome '); //输出: Welcome Haiyong
myFunction('Hello Mr.'); //输出: Hello Mr.Haiyong
根据上面的代码,即使在外部函数返回之后,内部函数(即,greetingInfo)也可以访问外部函数作用域(即 Welcome)中的变量。
28.什么是modules(模块)?
模块是指独立、可重用代码的小单元,也是许多 JavaScript 设计模式的基础。大多数 JavaScript 模块导出对象字面量、函数或构造函数
29.为什么需要模块?
以下是在 javascript 生态系统中使用模块的好处
- 可维护性
- 可重用性
- 命名空间
30.javascript中的作用域是什么?
作用域是在运行时代码的某些特定部分中变量、函数和对象的可访问性。换句话说,范围决定了代码区域中变量和其他资源的可见性。
31.什么是Service Worker?
Service Worker 基本上是一个在后台运行的脚本(JavaScript 文件),与网页分离并提供不需要网页或用户交互的功能。Service Worker 的一些主要功能是丰富的离线体验(离线第一个 Web 应用程序开发)、定期后台同步、推送通知、拦截和处理网络请求以及以编程方式管理响应缓存。
32.如何使用 Service Worker 操作 DOM?
Service Worker 不能直接访问 DOM。但是它可以通过响应通过postMessage接口发送的消息与它控制的页面进行通信,并且这些页面可以操作 DOM。
33.你如何在 Service Worker 重新启动时重用信息?
Service Worker 的问题在于它在不使用时会被终止,并在下次需要时重新启动,因此您不能依赖 Service Worker onfetch和onmessage处理程序中的全局状态。在这种情况下,服务工作者将有权访问 IndexedDB API,以便在重新启动时保持和重用。
34.什么是 IndexedDB?
IndexedDB 是用于客户端存储大量结构化数据(包括文件/blob)的低级 API。此 API 使用索引来启用此数据的高性能搜索。
35.什么是 web storage?
Web 存储是一种 API,它提供了一种机制,浏览器可以通过该机制以比使用 cookie 更直观的方式在用户浏览器中本地存储键/值对。Web 存储提供了两种在客户端存储数据的机制。
- 本地存储:它存储当前来源的数据,没有到期日期。
- 会话存储:存储一个会话的数据,关闭浏览器选项卡时数据丢失。
36.什么是 post message?
post message是一种启用 Window 对象之间的跨源通信的方法。(即,在页面和它产生的弹出窗口之间,或在页面和嵌入其中的 iframe 之间)。通常,当且仅当页面遵循同源策略(即页面共享相同的协议、端口号和主机)时,允许不同页面上的脚本相互访问。
37.什么是 Cookie ?
你可以在这篇文章中更详细地了解Cookie :
haiyong.blog.csdn.net/article/det…
cookie 是存储在您的计算机上以供浏览器访问的一段数据。Cookie 保存为键/值对。
例如,您可以创建一个名为 username 的 cookie,如下所示,
document.cookie = "username=Haiyong";
38.为什么需要 Cookie ?
Cookie 用于记住有关用户个人资料的信息(例如用户名)。它基本上包括两个步骤,
- 当用户访问网页时,用户个人资料可以存储在 cookie 中。
- 下次用户访问页面时,cookie 会记住用户配置文件。
39.cookie 中有哪些选项 ?
以下选项可用于 cookie,
默认情况下,cookie 会在浏览器关闭时被删除,但您可以通过设置到期日期(UTC 时间)来更改此行为。
document.cookie = "username=Haiyong; expires=Sat, 8 Jun 2019 12:00:00 UTC";
默认情况下,cookie 属于当前页面。但是您可以使用路径参数告诉浏览器 cookie 所属的路径。
document.cookie = "username=Haiyong; path=/services";
40.你如何删除cookie ?
您可以通过将到期日期设置为已通过日期来删除 cookie。在这种情况下,您不需要指定 cookie 值。 例如,您可以删除当前页面中的用户名 cookie,如下所示。document.cookie = "username=; expires=Fri, 07 Jun 2019 00:00:00 UTC; path=/;";
注意:您应该定义 cookie 路径选项以确保您删除正确的 cookie。除非您指定路径参数,否则某些浏览器不允许删除 cookie。
41.cookie、本地存储和会话存储有什么区别 ?
以下是 cookie、本地存储和会话存储之间的一些区别,
| 特征 | cookie | 本地存储 | 会话存储 | |
|---|---|---|---|---|
| 在客户端或服务器端访问 | 服务器端和客户端 | 仅客户端 | 仅客户端 | |
| Lifetime | 使用 Expires 选项配置 | 直到删除 | 直到选项卡关闭 | |
| SSL | 支持 | 支持的 | 不支持 | 不支持 |
| 最大数据大小 | 4KB | 5 MB | 5MB | |
| ⬆ 返回顶部 |
42.localStorage 和 sessionStorage 的主要区别是什么?
LocalStorage 与 SessionStorage 相同,但即使浏览器关闭并重新打开(即它没有过期时间),它也会保留数据,而在 sessionStorage 中,当页面会话结束时,数据会被清除。
43.你如何访问web 存储?
Window 对象实现了WindowLocalStorage和WindowSessionStorage对象,它们分别具有localStorage(window.localStorage) 和sessionStorage(window.sessionStorage) 属性。这些属性创建 Storage 对象的实例,通过该实例可以为特定域和存储类型(会话或本地)设置、检索和删除数据项。
例如,您可以读写本地存储对象,如下所示
localStorage.setItem('logo', document.getElementById('logo').value);
localStorage.getItem('logo');
44.会话存储有哪些可用的方法?
会话存储提供了读取、写入和清除会话数据的方法
// 将数据保存到 sessionStorage
sessionStorage.setItem('key', 'value');
// 从 sessionStorage 获取保存的数据
let data = sessionStorage.getItem('key');
// 从 sessionStorage 中删除保存的数据
sessionStorage.removeItem('key');
// 从 sessionStorage 中删除所有保存的数据
sessionStorage.clear();
45.什么是存储事件及其事件处理程序?
StorageEvent 是在另一个文档的上下文中更改存储区域时触发的事件。而 onstorage 属性是一个用于处理存储事件的 EventHandler。 语法如下
window.onstorage = functionRef;
让我们以记录存储键及其值的 onstorage 事件处理程序的示例用法为例
window.onstorage = function(e) {
console.log('The ' + e.key +
' key has been changed from ' + e.oldValue +
' to ' + e.newValue + '.');
};
46.为什么需要web 存储?
Web存储更安全,可以在本地存储大量数据,不影响网站性能。此外,信息永远不会传输到服务器。因此,这是比 Cookie 更推荐的方法。
47.你如何检查 Web 存储浏览器支持?
在使用网络存储之前,您需要检查浏览器对 localStorage 和 sessionStorage 的支持,
if (typeof(Storage) !== "undefined") {
// localStorage/sessionStorage 的代码。
} else {
// 对不起! 没有网络存储支持..
}
48.你如何检查web workers浏览器支持?
在使用之前,您需要检查浏览器对 Web Worker 的支持
if (typeof(Worker) !== "undefined") {
// Web worker支持的代码。
} else {
// 对不起! 没有 Web Worker 支持.
}
49.举个 web worker 的例子
您需要按照以下步骤开始使用网络工作者进行计数示例
创建 Web Worker 文件:您需要编写一个脚本来增加计数值。我们将其命名为 counter.js
let i = 0;
function timedCount() {
i = i + 1;
postMessage(i);
setTimeout("timedCount()",500);
}
timedCount();
这里使用 postMessage() 方法将消息回传到 HTML 页面
创建 Web Worker 对象:您可以通过检查浏览器支持来创建 Web Worker 对象。让我们将此文件命名为 web_worker_example.js
if (typeof(w) == "undefined") {
w = new Worker("counter.js");
}
我们可以接收来自网络工作者的消息
w.onmessage = function(event){
document.getElementById("message").innerHTML = event.data;
};
终止 Web Worker:Web Worker 将继续侦听消息(即使在外部脚本完成后),直到它被终止。您可以使用 terminate() 方法终止对消息的侦听。
w.terminate();
重用 Web Worker:如果将 worker 变量设置为 undefined,则可以重用代码
w = undefined;
50.web worker 对 DOM 的限制是什么?
WebWorker 无权访问以下 javascript 对象,因为它们是在外部文件中定义的
- 窗口对象
- 文档对象
- 父对象
51.什么是promise?
promise是一个对象,它可能会在未来的某个时间产生一个单一的值,其中有一个已解决的值或一个未解决的原因(例如,网络错误)。它将处于 3 种可能状态之一:已完成、已拒绝或未决。
Promise 创建的语法如下所示,
const promise = new Promise(function(resolve, reject) {
// promise description
})
承诺的用法如下,
const promise = new Promise(resolve => {
setTimeout(() => {
resolve("I'm a Promise!");
}, 5000);
}, reject => {
});
promise.then(value => console.log(value));
52.为什么需要promise?
Promise 用于处理异步操作。它们通过减少回调地狱和编写更干净的代码为回调提供了一种替代方法。
53.promise的三种状态是什么?
Promise 具有三种状态:
- Pending:这是操作开始前 Promise 的初始状态
- 已完成:此状态表示指定的操作已完成。
- Rejected:此状态表示操作未完成。在这种情况下,将抛出错误值。
54.什么是回调函数?
回调函数是作为参数传递给另一个函数的函数。这个函数在外部函数内部调用以完成一个动作。
我们举一个简单的例子来说明如何使用回调函数
function callbackFunction(name) {
console.log('Hello ' + name);
}
function outerFunction(callback) {
let name = prompt('Please enter your name.');
callback(name);
}
outerFunction(callbackFunction);
55.为什么我们需要回调?
回调是必需的,因为 javascript 是一种事件驱动的语言。这意味着 javascript 将在侦听其他事件的同时继续执行,而不是等待响应。 让我们举一个例子,第一个函数调用 API 调用(由 setTimeout 模拟)和下一个函数记录消息。
function firstFunction(){
// 模拟代码延迟
setTimeout( function(){
console.log('First function called');
}, 1000 );
}
function secondFunction(){
console.log('Second function called');
}
firstFunction();
secondFunction();
Output
// Second function called
// First function called
从输出中可以看出,javascript 没有等待第一个函数的响应,并且执行了剩余的代码块。因此,回调用于确保某些代码在其他代码完成执行之前不会执行。
56.什么是回调地狱?
回调地狱是一种具有多个嵌套回调的反模式,这使得在处理异步逻辑时代码难以阅读和调试。回调地狱看起来像下面,
async1(function(){
async2(function(){
async3(function(){
async4(function(){
....
});
});
});
});
57.什么是服务器发送事件?
服务器发送事件 (SSE) 是一种服务器推送技术,使浏览器能够通过 HTTP 连接从服务器接收自动更新,而无需求助于轮询。这些是一种单向通信通道 - 事件仅从服务器流向客户端。这已用于CSDN博客更新、股票价格更新、新闻提要等。
58.你如何接收服务器发送的事件通知?
EventSource 对象用于接收服务器发送的事件通知。例如,您可以从服务器接收消息,如下所示,
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("sse_generator.js");
source.onmessage = function(event) {
document.getElementById("output").innerHTML += event.data + "<br>";
};
}
59.你如何检查浏览器对服务器发送事件的支持?
您可以在使用之前对服务器发送的事件执行浏览器支持,如下所示,
if(typeof(EventSource) !== "undefined") {
// 支持服务器发送的事件。 让我们在这里有一些代码!
} else {
// 不支持服务器发送的事件
}
60.服务器发送的事件有哪些可用的事件?
以下是可用于服务器发送事件的事件列表
| 活动 | 说明 |
|---|---|
| 打开 | 它在打开与服务器的连接时使用 |
| 留言 | 收到消息时使用此事件 |
| 错误 | 发生错误时发生 |
61.promise的主要规则是什么?
promise必须遵循一组特定的规则,
- promise是提供符合标准的.then()方法的对象
- 挂起的promise可以转换为已完成或拒绝状态
- 已完成或被拒绝的promise已解决,并且不得转换为任何其他状态。
- 一旦promise被解决,价值就不能改变。
62.回调中的回调是什么?
您可以将一个回调嵌套在另一个回调中,以依次执行操作。这被称为回调中的回调。
loadScript('/script1.js', function(script) {
console.log('first script is loaded');
loadScript('/script2.js', function(script) {
console.log('second script is loaded');
loadScript('/script3.js', function(script) {
console.log('third script is loaded');
// 加载所有脚本后
});
})
});
63.什么是promise chaining?
使用 Promise 一个接一个地执行一系列异步任务的过程称为 Promise chaining。让我们举一个计算最终结果的promise chaining的例子,
new Promise(function(resolve, reject) {
setTimeout(() => resolve(1), 1000);
}).then(function(result) {
console.log(result); // 1
return result * 2;
}).then(function(result) {
console.log(result); // 2
return result * 3;
}).then(function(result) {
console.log(result); // 6
return result * 4;
});
在上述处理程序中,结果通过以下工作流程传递给 .then() 处理程序链,
1.最初的promise 在 1 秒内解决, 2.在.then通过记录 result(1) 调用该处理程序之后,然后返回一个值为 result * 2 的承诺。 3.之后,.then通过记录 result(2)将值传递给下一个处理程序,并返回一个结果为 * 3 的承诺。 4.最后.then通过记录 result(6)传递给最后一个处理程序的值并返回一个结果为 * 4 的承诺。
64.什么是 promise.all?
Promise.all 是一个将一系列承诺作为输入(可迭代)的承诺,当所有承诺都得到解决或其中任何一个被拒绝时,它就会得到解决。例如,promise.all 方法的语法如下,
Promise.all([Promise1, Promise2, Promise3]) .then(result) => { console.log(result) }) .catch(error => console.log(`Error in promises ${error}`))
==注意==:请记住,承诺的顺序(输出结果)按照输入顺序进行维护。
65.promise中race方法的目的是什么?
Promise.race() 方法将返回首先解决或拒绝的承诺实例。让我们举一个race()方法的例子,其中promise2首先被解析
var promise1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, 'one');
});
var promise2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'two');
});
Promise.race([promise1, promise2]).then(function(value) {
console.log(value); // "two" // 两个 promise 都会解决,但 promise2 更快
});
66.什么是javascript中的严格模式?
严格模式是 ECMAScript 5 中的一项新功能,它允许您将程序或函数置于“严格”操作上下文中。通过这种方式,它可以防止执行某些操作并引发更多异常。文字表达式"use strict";指示浏览器在严格模式下使用 javascript 代码。
67.为什么需要严格模式?
通过将“错误语法”通知为实际错误,严格模式对于编写“安全”JavaScript 很有用。例如,它消除了通过抛出错误而意外创建全局变量的情况,并且还会在分配给不可写属性、getter-only 属性、不存在的属性、不存在的变量或不存在的变量时引发错误。现有的对象。
68.你如何声明严格模式?
严格模式是通过添加“use strict”来声明的;到脚本或函数的开头。 如果在脚本的开头声明,则它具有全局作用域。
"use strict";
x = 3.14; // 这将导致错误,因为 x 未声明
如果你在函数内部声明,它具有局部作用域
x = 3.14; // 这不会导致错误。
myFunction();
function myFunction() {
"use strict";
y = 3.14; // This will cause an error
}
69.双感叹号的目的是什么?
双感叹号或否定 (!!) 确保结果类型是布尔值。如果它是假的(例如 0、空、未定义等),它将是假的,否则为真。
例如,您可以使用以下表达式测试 IE 版本,
let isIE8 = false;
isIE8 = !! navigator.userAgent.match(/MSIE 8.0/);
console.log(isIE8); // returns true or false
如果您不使用此表达式,则它返回原始值。
console.log(navigator.userAgent.match(/MSIE 8.0/)); // 返回一个数组或 null
70.删除运算符的目的是什么?
delete 关键字用于删除属性及其值。
var user= {name: "Haiyong", age:20};
delete user.age;
console.log(user); // {name: "Haiyong"}
71.什么是typeof运算符?
您可以使用 JavaScript typeof 运算符来查找 JavaScript 变量的类型。它返回变量或表达式的类型。
typeof "Haiyong Abraham" // Returns "string"
typeof (1 + 2) // Returns "number"
72.什么是未定义属性?
undefined 属性表示一个变量没有被赋值,或者根本没有声明。未定义值的类型也是未定义的。
var user; // 值未定义,类型未定义
console.log(typeof(user)) //未定义
任何变量都可以通过将值设置为 undefined 来清空。
user = undefined
73.什么是空值?
值 null 表示有意缺少任何对象值。它是 JavaScript 的原始值之一。空值的类型是对象。 您可以通过将值设置为 null 来清空变量。
var user = null;
console.log(typeof(user)) //object
74.null 和 undefined 有什么区别?
以下是 null 和 undefined 之间的主要区别,
| null | undefined |
|---|---|
| 它是一个赋值值,表示变量不指向任何对象。 | 它不是已声明变量但尚未赋值的赋值值。 |
| null 的类型是object | undefined 的类型是 undefined |
| 空值是一个原始值,表示空、空或不存在的引用。 | 未定义值是在变量尚未赋值时使用的原始值。 |
| 表示变量没有值 | 表示没有变量本身 |
| 执行原始操作时转换为零 (0) | 执行原始操作时转换为 NaN |
75.什么是eval?
eval() 函数计算表示为字符串的 JavaScript 代码。字符串可以是 JavaScript 表达式、变量、语句或语句序列。
console.log(eval('1 + 2')); // 3
76.Window和Document有什么区别?
以下是Window和Document之间的主要区别,
| Window | Document |
|---|---|
| 它是任何网页中的根级元素 | 它是 window 对象的直接子级。这也称为文档对象模型(DOM) |
| 默认情况下,窗口对象在页面中隐式可用 | 您可以通过 window.document 或 document 访问它。 |
| 它有alert()、confirm()等方法和文档、位置等属性 | 它提供了 getElementById、getElementByTagName、createElement 等方法 |
77.你如何在 javascript 中访问历史记录?
window.history 对象包含浏览器的历史记录。您可以使用 back() 和 next() 方法加载历史记录中的上一个和下一个 URL。
function goBack() {
window.history.back()
}
function goForward() {
window.history.forward()
}
==注意==:您也可以在没有窗口前缀的情况下访问历史记录。
78.你如何检测大写锁定键是否打开?
所述mouseEvent getModifierState()用于返回一个布尔值,指示指定的修饰键是否被激活。CapsLock、ScrollLock 和 NumLock 等修饰符在单击时激活,再次单击时停用。
让我们以一个输入元素为例来检测 CapsLock 开/关行为,
<input type="password" onmousedown="enterInput(event)">
<p id="feedback"></p>
<script>
function enterInput(e) {
var flag = e.getModifierState("CapsLock");
if(flag) {
document.getElementById("feedback").innerHTML = "CapsLock activated";
} else {
document.getElementById("feedback").innerHTML = "CapsLock not activated";
}
}
</script>
79.什么是isNaN?
isNaN() 函数用于确定一个值是否为非法数字(Not-a-Number)。即,如果该值等于 NaN,则此函数返回 true。否则返回false。
isNaN('Hello') //true
isNaN('100') //false
80.未声明变量和未定义变量有什么区别?
以下是未声明和未定义变量之间的主要区别,
| undeclared | undefined |
|---|---|
| 这些变量不存在于程序中且未声明 | 这些在程序中声明但没有赋值的变量 |
| 如果您尝试读取未声明变量的值,则会遇到运行时错误 | 如果您尝试读取未定义变量的值,则会返回未定义值。 |
| ⬆ 返回顶部 | |
| 回到第50题 |
81.什么是全局变量?
全局变量是那些在整个代码长度内都可用的变量,没有任何作用域。var 关键字用于声明局部变量,但如果省略它,它将成为全局变量
msg = "Hello" // var 缺失,它成为全局变量
82.全局变量有什么问题?
全局变量的问题是局部作用域和全局作用域的变量名冲突。调试和测试依赖全局变量的代码也很困难。
83.什么是 NaN 属性?
NaN 属性是一个全局属性,表示“非数字”值。即,它表示一个值不是一个合法的数字。在程序中很少使用 NaN,但在少数情况下可以用作返回值
Math.sqrt(-1)
parseInt("Hello")
84.isFinite 函数的目的是什么?
isFinite() 函数用于确定一个数是否是一个有限的合法数。如果值为 +infinity、-infinity 或 NaN(非数字),则返回 false,否则返回 true。
isFinite(Infinity); // false
isFinite(NaN); // false
isFinite(-Infinity); // false
isFinite(100); // true
85.什么是event flow(事件流)?
事件流是在网页上接收事件的顺序。当您单击嵌套在各种其他元素中的元素时,在您的单击实际到达其目的地或目标元素之前,它必须首先触发其每个父元素的单击事件,从全局窗口对象的顶部开始。
事件流有两种方式
- 从上到下(事件捕获)
- 从下到上(事件冒泡)
86.什么是event bubbling(事件冒泡)?
事件冒泡是一种事件传播,其中事件首先在最内层的目标元素上触发,然后在同一嵌套层次结构中的目标元素的祖先(父级)上依次触发,直到到达最外层的 DOM 元素。
87.什么是event capturing(事件捕获)?
事件捕获是一种事件传播,其中事件首先被最外层元素捕获,然后在同一嵌套层次结构中的目标元素的后代(子级)上连续触发,直到它到达最内层 DOM 元素。
88.你如何使用 JavaScript 提交表单?
您可以使用 JavaScript 提交表单,使用 document.form[0].submit()。使用 onsubmit 事件处理程序提交所有表单输入的信息
function submit() {
document.form[0].submit();
}
89.你如何找到操作系统详细信息?
window.navigator 对象包含有关访问者浏览器操作系统详细信息的信息。一些操作系统属性在平台属性下可用,
console.log(navigator.platform);
90.document load 和 DOMContentLoaded 事件有什么区别?
DOMContentLoaded当初始 HTML 文档完全加载并解析完毕,无需等待资产(样式表、图像和子框架)完成加载时,将触发该事件。而当整个页面加载时会触发 load 事件,包括所有依赖资源(样式表、图像)。
91.Native 、Host 和User objects之间有什么区别?
Native objects是 ECMAScript 规范定义的 JavaScript 语言的一部分的对象。例如,ECMAScript 规范中定义的 String、Math、RegExp、Object、Function 等核心对象。Host objects是浏览器或运行时环境(节点)提供的对象。例如,窗口、XmlHttpRequest、DOM节点等被视为宿主对象。User objects是在 javascript 代码中定义的对象。例如,为配置文件信息创建的用户对象。
92.用于调试 JavaScript 代码的工具或技术有哪些?
您可以使用以下工具或技术来调试 javascript
- Chrome 开发者工具
- debugger statement
- 较老的 console.log 语句
93.promises相对于回调的优缺点是什么?
优点:
1.它避免了不可读的回调地狱 2.使用 .then() 轻松编写顺序异步代码 3.使用 Promise.all() 轻松编写并行异步代码 4.解决回调的一些常见问题(回调太晚、太早、多次和吞下错误/异常)
缺点:
1.它编写了少量的复杂代码 2.如果不支持 ES6,你需要加载一个 polyfill
94.attribute 和 property有什么区别?
Attributes 在 HTML 标记上定义,而properties 在 DOM 上定义。例如,下面的 HTML 元素有两个attributes 类型和值,
<input type="text" value="Name:">
您可以检索attribute 值如下,
const input = document.querySelector('input');
console.log(input.getAttribute('value')); // Good morning
console.log(input.value); // Good morning
将文本字段的值更改为“Good evening”后,它变得像
console.log(input.getAttribute('value')); // Good morning
console.log(input.value); // Good evening
95.什么是 same-origin policy(同源策略)?
同源策略是一种防止 JavaScript 跨域边界发出请求的策略。源定义为 URI 方案、主机名和端口号的组合。如果启用此策略,则它会阻止一个页面上的恶意脚本使用文档对象模型 (DOM) 获取对另一个网页上的敏感数据的访问权限。
96.void 0的目的是什么?
void(0) 用于防止页面刷新。这将有助于消除不需要的副作用,因为它将返回未定义的原始值。它通常用于使用 href="JavaScript:Void(0);" 的 HTML 文档。 一个元素内。 即,当您单击链接时,浏览器会加载一个新页面或刷新同一页面。 但是使用此表达式将阻止这种行为。
例如,下面的链接在不重新加载页面的情况下通知消息
<a href="JavaScript:void(0);" onclick="alert('Well done!')">Click Me!</a>
97.JavaScript 是编译型语言还是解释型语言?
JavaScript 是一种解释型语言,而不是一种编译型语言。浏览器中的解释器读取 JavaScript 代码,解释每一行,然后运行它。如今,现代浏览器使用一种称为即时 (JIT) 编译的技术,该技术在 JavaScript 即将运行时将其编译为可执行的字节码。
98.JavaScript 是区分大小写的语言吗?
是的,JavaScript 是一种区分大小写的语言。语言关键字、变量、函数和对象名称以及任何其他标识符必须始终使用一致的大写字母输入。
99.Java 和 JavaScript 之间有什么关系吗?
不,它们完全是两种不同的编程语言,彼此没有任何关系。但是它们都是面向对象的编程语言,并且像许多其他语言一样,它们的基本功能(if、else、for、switch、break、continue 等)遵循类似的语法。
具体区别可以查看我这篇文章:
haiyong.blog.csdn.net/article/det…
100.什么是event?
event是发生在 HTML 元素上的“事物”。在 HTML 页面中使用 JavaScript 时,JavaScript 可以react处理这些事件。HTML 事件的一些示例是,
- 网页已完成加载
- 输入字段已更改
- 按钮被点击
让我们描述一下按钮元素的点击事件的行为,
<!doctype html>
<html>
<head>
<script>
function greeting() {
alert('Hello! Good morning');
}
</script>
</head>
<body>
<button type="button" onclick="greeting()">Click me</button>
</body>
</html>
我已经写了很长一段时间的技术博客,并且主要通过CSDN发表,这是我的一篇面试题文章。希望你们会喜欢!
如果你真的从这篇文章中学到了一些新东西,喜欢它,收藏它并与你的小伙伴分享。🤗最后,不要忘了❤或📑支持一下哦