分享

14万字 | 400多道JavaScript 面试题及详细答案(建议收藏)

 海拥 2021-11-30

14万字 | 400 多道 JavaScript 面试题 🎓 有答案 🌠

为了方便手机阅览,我在必要位置都放了回顶部或者回对应问题的链接
在这里插入图片描述

编号问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
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 提供了严格(===, !==) 和类型转换(==, !=) 相等比较。严格运算符考虑变量的类型,而非严格运算符根据变量的值进行类型校正/转换。严格的运算符遵循以下不同类型的条件,

  1. 当两个字符串具有相同的字符序列、相同的长度以及相应位置的相同字符时,它们是严格相等的。

  2. 当两个数字在数值上相等时,它们严格相等。即,具有相同的数值。这里有两种特殊情况,

NaN 不等于任何东西,包括 NaN。
正零和负零彼此相等。

  1. 如果两个布尔操作数都为真或都为假,则两个布尔操作数严格相等。

  2. 如果两个对象引用同一个对象,则它们严格相等。

  3. Null 和 Undefined 类型与 === 不相等,但与 == 相等。即, null===undefined --> falsenull==undefined --> true
    一些涵盖上述情况的例子,

0 == false   // true0 === false  // false1 == "1"     // true1 === "1"    // falsenull == undefined // truenull === 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));// 6const curryUnaryFunction = a => b => c => a + b + c;curryUnaryFunction (1); // return a function: b => c =>  1 + b + ccurryUnaryFunction (1) (2); // return a function: c => 3 + ccurryUnaryFunction (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 1console.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 有什么区别?

以表格格式列出差异

varlet
它从 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 calculatedconsole.log(addition(20)); //输出: 40 cached

25.什么是Hoisting(变量提升)?

Hoisting是一种 JavaScript 机制,其中变量和函数声明在代码执行之前被移动到其作用域的顶部。请记住,JavaScript 只提升声明,而不是初始化。
我们举一个简单的变量提升的例子,

console.log(message); //输出: undefinedvar 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 HaiyongmyFunction('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 onfetchonmessage处理程序中的全局状态。在这种情况下,服务工作者将有权访问 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 :

https://haiyong.blog.csdn.net/article/details/117837835

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支持支持的不支持
最大数据大小4KB5 MB5MB

42.localStorage 和 sessionStorage 的主要区别是什么?

LocalStorage 与 SessionStorage 相同,但即使浏览器关闭并重新打开(即它没有过期时间),它也会保留数据,而在 sessionStorage 中,当页面会话结束时,数据会被清除。


43.你如何访问web 存储?

Window 对象实现了WindowLocalStorageWindowSessionStorage对象,它们分别具有localStorage(window.localStorage) 和sessionStorage(window.sessionStorage) 属性。这些属性创建 Storage 对象的实例,通过该实例可以为特定域和存储类型(会话或本地)设置、检索和删除数据项。
例如,您可以读写本地存储对象,如下所示

localStorage.setItem('logo', document.getElementById('logo').value);localStorage.getItem('logo');

44.会话存储有哪些可用的方法?

会话存储提供了读取、写入和清除会话数据的方法

// 将数据保存到 sessionStoragesessionStorage.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 之间的主要区别,

nullundefined
它是一个赋值值,表示变量不指向任何对象。它不是已声明变量但尚未赋值的赋值值。
null 的类型是objectundefined 的类型是 undefined
空值是一个原始值,表示空、空或不存在的引用。未定义值是在变量尚未赋值时使用的原始值。
表示变量没有值表示没有变量本身
执行原始操作时转换为零 (0)执行原始操作时转换为 NaN

75.什么是eval?

eval() 函数计算表示为字符串的 JavaScript 代码。字符串可以是 JavaScript 表达式、变量、语句或语句序列。

console.log(eval('1 + 2')); // 3

76.Window和Document有什么区别?

以下是Window和Document之间的主要区别,

WindowDocument
它是任何网页中的根级元素它是 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') //trueisNaN('100') //false

80.未声明变量和未定义变量有什么区别?

以下是未声明和未定义变量之间的主要区别,

undeclaredundefined
这些变量不存在于程序中且未声明这些在程序中声明但没有赋值的变量
如果您尝试读取未声明变量的值,则会遇到运行时错误如果您尝试读取未定义变量的值,则会返回未定义值。

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);  // falseisFinite(NaN);       // falseisFinite(-Infinity); // falseisFinite(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 morningconsole.log(input.value); // Good morning

将文本字段的值更改为“Good evening”后,它变得像

console.log(input.getAttribute('value')); // Good morningconsole.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 等)遵循类似的语法。

具体区别可以查看我这篇文章:

https://haiyong.blog.csdn.net/article/details/117409345


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>

101.谁创造了 JavaScript ?

JavaScript 是由 Brendan Eich 于 1995 年在 Netscape Communications 期间创建的。 最初它是以 Mocha 的名义开发的,但后来在 Netscape 的测试版中首次发布时,该语言被正式称为 LiveScript。当时Sun公司和网景公司有合作,SUN公司注册了“JavaScript”商标,两公司协商后把LiveScript改成了现在的JavaScript。


102.preventDefault 方法有什么用?

如果事件是可取消的,则 preventDefault() 方法会取消该事件,这意味着属于该事件的默认操作或行为将不会发生。例如,单击提交按钮时阻止表单提交和单击超链接时阻止打开页面 URL 是一些常见用例。

 document.getElementById("link").addEventListener("click", function(event){
  event.preventDefault();
 });

注意:请记住,并非所有事件都可以取消。


103.stopPropagation方法有什么用?

stopPropagation 方法用于阻止事件在事件链中向上冒泡。例如,以下带有 stopPropagation 方法的嵌套 div 在单击嵌套 div(Div1) 时可防止默认事件传播

 <p>Click DIV1 Element</p>
 <div onclick="secondFunc()">DIV 2   <div onclick="firstFunc(event)">DIV 1</div>
 </div>

 <script>
 function firstFunc(event) {
   alert("DIV 1");
   event.stopPropagation();
 }

 function secondFunc() {
   alert("DIV 2");
 }
 </script>

104.return false 涉及哪些步骤?

事件处理程序中的 return false 语句执行以下步骤,

1.首先它停止浏览器的默认操作或行为。
2.它阻止事件传播 DOM
3.停止回调执行并在调用时立即返回。


105.什么是BOM(浏览器对象模型)?

浏览器对象模型 (BOM) 允许 JavaScript 与浏览器“对话”。它由作为窗口子项的对象导航器、历史记录、屏幕、位置和文档组成。浏览器对象模型不是标准化的,可以根据不同的浏览器而变化。


106.setTimeout有什么用?

setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。例如,让我们使用 setTimeout 方法在 2 秒后记录一条消息,

 setTimeout(function(){ console.log("Good morning"); }, 2000);

107.setInterval有什么用?

setInterval() 方法用于以指定的时间间隔(以毫秒为单位)调用函数或计算表达式。例如,让我们使用 setInterval 方法在 2 秒后记录一条消息,

 setInterval(function(){ console.log("Good morning"); }, 2000);

108.为什么 JavaScript 被视为单线程?

JavaScript 是一种单线程语言。因为语言规范不允许程序员编写代码以便解释器可以在多个线程或进程中并行运行其中的一部分。而像 java、go、C++ 这样的语言可以制作多线程和多进程程序。


109.什么是event delegation(事件委托)?

事件委托是一种侦听事件的技术,您可以委托一个父元素作为其内部发生的所有事件的侦听器。

例如,如果您想检测特定表单内的字段变化,您可以使用事件委托技术,

 var form = document.querySelector('#registration-form');
 // 听从表单内字段的更改
 form.addEventListener('input', function (event) {
 // 记录已更改的字段
 console.log(event.target);
 }, false);

110.什么是 ECMAScript?

ECMAScript 是构成 JavaScript 基础的脚本语言。ECMAScript 由 ECMA 国际标准组织在 ECMA-262 和 ECMA-402 规范中标准化。ECMAScript 的第一版于 1997 年发布。


111.什么是 JSON?

JSON(JavaScript Object Notation)是一种用于数据交换的轻量级格式。它基于 JavaScript 语言的一个子集,对象是在 JavaScript 中构建的。


112.JSON的语法规则是什么?

下面是 JSON 的语法规则列表

1.数据在名称/值对中
2.数据以逗号分隔
3.花括号容纳对象
4.方括号保存数组


113.JSON 字符串化的目的是什么?

向 Web 服务器发送数据时,数据必须采用字符串格式。您可以通过使用 stringify() 方法将 JSON 对象转换为字符串来实现此目的。

 var userJSON = {'name': 'Haiyong', age: 31}
 var userString = JSON.stringify(user);
 console.log(userString); //"{"name":"Haiyong","age":31}"

114.你如何解析 JSON 字符串?

从 Web 服务器接收数据时,数据始终为字符串格式。但是您可以使用 parse() 方法将此字符串值转换为 javascript 对象。

 var userString = '{"name":"Haiyong","age":31}';
 var userJSON = JSON.parse(userString);
 console.log(userJSON);// {name: "Haiyong", age: 31}

115.为什么需要 JSON?

在浏览器和服务器之间交换数据时,数据只能是文本。由于 JSON 仅为文本,因此它可以轻松地与服务器之间进行发送和发送,并可用作任何编程语言的数据格式。


116.什么是 PWA?

渐进式 Web 应用程序 (Progressive web applications) 是一种通过 Web 交付的移动应用程序,使用常见的 Web 技术(包括 HTML、CSS 和 JavaScript)构建。这些 PWA 部署到服务器上,通过 URL 访问,并由搜索引擎索引。


117.clearTimeout 方法的目的是什么?

javascript 中使用 clearTimeout() 函数来清除之前由 setTimeout() 函数设置的超时。即, setTimeout() 函数的返回值存储在一个变量中,并将其传递给 clearTimeout() 函数以清除计时器。

例如,下面的 setTimeout 方法用于在 3 秒后显示消息。可以通过 clearTimeout() 方法清除此超时。

 <script>
 var msg;
 function greeting() {
    alert('Good morning');
 }
 function start() {
   msg =setTimeout(greeting, 3000);

 }

 function stop() {
     clearTimeout(msg);
 }
 </script>

118.clearInterval 方法的目的是什么?

javascript 中使用 clearInterval() 函数清除 setInterval() 函数设置的间隔。即, setInterval() 函数返回的返回值存储在一个变量中,并将其传递给 clearInterval() 函数以清除间隔。

例如,下面的 setInterval 方法用于每 3 秒显示一次消息。可以通过 clearInterval() 方法清除此间隔。

 <script>
 var msg;
 function greeting() {
    alert('Good morning');
 }
 function start() {
   msg = setInterval(greeting, 3000);

 }

 function stop() {
     clearInterval(msg);
 }
 </script>

119.你如何在javascript中重定向新页面?

在 vanilla javascript 中,您可以使用locationwindow 对象的属性重定向到新页面。语法如下,

 function redirect() {
    window.location.href = 'newPage.html';
 }

120.你如何检查一个字符串是否包含一个子字符串?

有 3 种可能的方法来检查字符串是否包含子字符串,

1.使用 includes: ES6 提供的String.prototype.includes方法来测试字符串是否包含子字符串

 var mainString = "hello", subString = "hell";
 mainString.includes(subString)

2.使用 indexOf:在 ES5 或更旧的环境中,您可以使用String.prototype.indexOfwhich 返回子字符串的索引。如果索引值不等于 -1,则表示子字符串存在于主字符串中。

 var mainString = "hello", subString = "hell";
 mainString.indexOf(subString) !== -1

3.使用 RegEx:高级解决方案是使用正则表达式的测试方法( RegExp.test),它允许针对正则表达式进行测试

 var mainString = "hello", regex = /hell/;
 regex.test(mainString)

121.你如何在 javascript 中验证电子邮件?

您可以使用正则表达式在 javascript 中验证电子邮件。建议在服务器端而不是客户端进行验证。因为可以在客户端禁用 javascript。

 function validateEmail(email) {
     var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
     return re.test(String(email).toLowerCase());
 }

上面的正则表达式接受 unicode 字符。


122.你如何使用 javascript 获取当前 url?

您可以使用window.location.href表达式来获取当前的 url 路径,也可以使用相同的表达式来更新 URL。您也可以document.URL用于只读目的,但此解决方案在 FF 中存在问题。

 console.log('location.href', window.location.href); // 返回完整 URL

123.location对象的各种url属性是什么?

以下Location对象属性可用于访问页面的 URL 组件,

1.href - 整个 URL
2.protocol - URL 的协议
3.host - URL 的主机名和端口
4.hostname - URL 的主机名
5.port - URL 中的端口号
6.pathname - URL 的路径名
7.search - URL 的查询部分
8.hash - URL 的锚点部分


124.如何在javascript中获取查询字符串值?

您可以使用 URLSearchParams 在 javascript 中获取查询字符串值。让我们看一个从 URL 查询字符串中获取客户端代码值的示例,

 const urlParams = new URLSearchParams(window.location.search);
 const clientCode = urlParams.get('clientCode');

125.如何检查对象中是否存在键?

您可以使用三种方法检查对象中是否存在键,

使用 in 运算符:无论对象中是否存在键,您都可以使用 in 运算符

 "key" in obj

如果你想检查一个键是否不存在,记得使用括号,

 !("key" in obj)

使用 hasOwnProperty 方法:您可以使用hasOwnProperty专门测试对象实例的属性(而不是继承的属性)

 obj.hasOwnProperty("key") // true

使用未定义的比较:如果从对象访问不存在的属性,则结果是未定义的。让我们将属性与 undefined 进行比较以确定该属性的存在。

 const user = {
   name: 'Haiyong'
 };

 console.log(user.name !== undefined);     // true
 console.log(user.nickName !== undefined); // false

126.你如何循环或枚举 javascript 对象?

您可以使用for-in循环来循环遍历 javascript 对象。您还可以确保您获得的密钥是对象的实际属性,而不是来自使用hasOwnProperty方法的原型。

 var object = {
     "k1": "value1",
     "k2": "value2",
     "k3": "value3"
 };

 for (var key in object) {
     if (object.hasOwnProperty(key)) {
         console.log(key + " -> " + object[key]); // k1 -> value1 ...
     }
 }

127.你如何测试一个空对象?

基于 ECMAScript 版本有不同的解决方案

使用对象条目(ECMA 7+):您可以使用对象条目长度和构造函数类型。

 Object.entries(obj).length === 0 && obj.constructor === Object // Since date object length is 0, you need to check constructor check as well

使用对象键(ECMA 5+):您可以使用对象键长度和构造函数类型。

 Object.keys(obj).length === 0 && obj.constructor === Object // Since date object length is 0, you need to check constructor check as well

将 for-in 与 hasOwnProperty(ECMA 5 之前)一起使用:您可以将 for-in 循环与 hasOwnProperty 一起使用。

 function isEmpty(obj) {
   for(var prop in obj) {
     if(obj.hasOwnProperty(prop)) {
       return false;
     }
   }

   return JSON.stringify(obj) === JSON.stringify({});
 }

128.什么是参数对象?

arguments 对象是一个类似数组的对象,可在函数内部访问,其中包含传递给该函数的参数的值。例如,让我们看看如何在 sum 函数中使用 arguments 对象,

 function sum() {
     var total = 0;
     for (var i = 0, len = arguments.length; i < len; ++i) {
         total += arguments[i];
     }
     return total;
 }

 sum(1, 2, 3) // returns 6

注意:您不能在参数对象上应用数组方法。但是您可以转换为常规数组,如下所示

 var argsArray = Array.prototype.slice.call(arguments);

129.你如何使字符串的第一个字母大写?

您可以创建一个函数,该函数使用一系列字符串方法(例如 charAt、toUpperCase 和 slice 方法)来生成首字母大写的字符串。

 function capitalizeFirstLetter(string) {
     return string.charAt(0).toUpperCase() + string.slice(1);
 }

130.for循环的优缺点是什么?

for 循环是 JavaScript 中常用的迭代语法。它有利有弊

优点

  • 适用于各种环境

  • 您可以使用 break 和 continue 流控制语句

缺点

  • 太冗长

  • Imperative(命令式编程)

  • 您可能会面临一次一次的错误


131.你如何在javascript中显示当前日期?

您可以使用new Date()生成包含当前日期和时间的新 Date 对象。例如,让我们以 mm/dd/yyyy 显示当前日期

 var today = new Date();
 var dd = String(today.getDate()).padStart(2, '0');
 var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
 var yyyy = today.getFullYear();

 today = mm + '/' + dd + '/' + yyyy;
 document.write(today);

132.你如何比较两个日期对象?

您需要使用 date.getTime() 方法来比较日期值而不是比较运算符(==!====!== 运算符)

 var d1 = new Date();
 var d2 = new Date(d1);
 console.log(d1.getTime() === d2.getTime()); //True
 console.log(d1 === d2); // False

133.你如何检查一个字符串是否以另一个字符串开头?

您可以使用 ECMAScript 6 的String.prototype.startsWith()方法来检查一个字符串是否以另一个字符串开头。但并非所有浏览器都支持它。让我们看一个例子来看看这个用法,

 "Good morning".startsWith("Good"); // true
 "Good morning".startsWith("morning"); // false

134.你如何在javascript中修剪字符串?

JavaScript 为字符串类型提供了一种修剪方法来修剪出现在字符串开头或结尾的任何空格。

 "  Hello World   ".trim(); //Hello World

如果您的浏览器(<IE9)不支持此方法,那么您可以使用下面的 polyfill。

 if (!String.prototype.trim) {
     (function() {
         // 确保我们修剪 BOM 和 NBSP
         var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
         String.prototype.trim = function() {
             return this.replace(rtrim, '');
         };
     })();
 }

135.你如何在javascript中添加一个键值对?

向对象添加新属性有两种可能的解决方案。让我们以一个简单的对象来解释这些解决方案。

 var object = {
     key1: value1,
     key2: value2 };

使用点表示法:当您知道属性的名称时,此解决方案很有用

 object.key3 = "value3";

使用方括号表示法:当属性的名称是动态确定的时,此解决方案很有用。

 obj["key3"] = "value3";

136.'!–’ 符号是否表示一个特殊运算符?

不,不是特殊运算符。但它是 2 个标准运算符的组合

逻辑否定(!)
前缀递减 (–)
首先,该值减一,然后测试它是否等于零,以确定真/假值。


137.你如何为变量分配默认值?

您可以使用逻辑或运算符 || 在赋值表达式中提供默认值。 语法如下所示,

 var a = b || c;

根据上面的表达式,只有当 'b’ 为假(如果为空、假、未定义、0、空字符串或 NaN)时,变量 'a’ 将获得 'c’ 的值,否则 'a’ 将获得’b’ 的值。


138.你如何定义多行字符串?

您可以使用“\”字符后跟行终止符来定义多行字符串文字。

 var str = "This is a  very lengthy  sentence!";

但是如果你在 '’ 字符后面有一个空格,代码看起来完全一样,但它会引发一个 SyntaxError。


139.什么是app shell model?

application shell (或者是 app shell)架构是构建渐进式 Web 应用程序的一种方式,该应用程序可以可靠且即时地加载到用户的屏幕上,类似于您在本机应用程序中看到的内容。这对于在没有网络的情况下快速将一些初始 HTML 显示到屏幕上很有用。


140.我们可以为函数定义属性吗?

是的,我们可以为函数定义属性,因为函数也是对象。

 fn = function(x) {
    //函数代码在这里
 }

 fn.name = "Haiyong";

 fn.profile = function(y) {
   //配置文件代码在这里
 }

141.找到函数期望的参数数量的方法是什么?

您可以使用function.length语法来查找函数所需的参数数量。让我们举一个sum计算数字和的函数的例子,

 function sum(num1, num2, num3, num4){
     return num1 + num2 + num3 + num4;
 }
 sum.length // 4 是预期的参数数量。

142.什么是 polyfill?

polyfill 是一段 JS 代码,用于在本身不支持它的旧浏览器上提供现代功能。例如,Silverlight 插件 polyfill 可用于模拟 Microsoft Internet Explorer 7 上的 HTML Canvas 元素的功能。


143.什么是 break 和 continue 语句?

break 语句用于“跳出”循环。即,它中断循环并在循环后继续执行代码。

 for (i = 0; i < 10; i++) {
   if (i === 5) { break; }
   text += "Number: " + i + "<br>";
 }

continue 语句用于“跳过”循环中的一次迭代。即,如果出现指定条件,它会中断一次迭代(在循环中),并继续循环中的下一次迭代。

 for (i = 0; i < 10; i++) {
     if (i === 5) { continue; }
     text += "Number: " + i + "<br>";
 }

144.什么是js标签?

label 语句允许我们在 JavaScript 中命名循环和块。然后我们可以使用这些标签稍后引用代码。例如,下面带有标签的代码避免在数字相同时打印数字,

 var i, j;

 loop1:
 for (i = 0; i < 3; i++) {
    loop2:
    for (j = 0; j < 3; j++) {
       if (i === j) {
          continue loop1;
       }
       console.log('i = ' + i + ', j = ' + j);
    }
 }

 // 输出:
 //   "i = 1, j = 0"
 //   "i = 2, j = 0"
 //   "i = 2, j = 1"

145.将声明放在首位有什么好处?

建议将所有声明保留在每个脚本或函数的顶部。这样做的好处是,

1.提供更清晰的代码
2.它提供了一个查找局部变量的地方
3.轻松避免不需要的全局变量
4.它减少了不需要的重新声明的可能性


146.初始化变量有什么好处?

由于以下好处,建议初始化变量,

1.它提供了更清晰的代码
2.它提供了一个初始化变量的地方
3.避免代码中的未定义值


147.创建新对象的建议是什么?

建议避免使用new Object(). 相反,您可以根据它的类型初始化值来创建对象。

1.分配 {} 而不是 new Object()
2.分配 “” 而不是 new String()
3.分配 0 而不是 new Number()
4.分配 false 而不是 new Boolean()
5.分配 [] 而不是 new Array()
6.分配 /()/ 而不是 new RegExp()
7.赋值 function (){} 而不是 new Function()

您可以将它们定义为示例,

 var v1 = {};
 var v2 = "";
 var v3 = 0;
 var v4 = false;
 var v5 = [];
 var v6 = /()/;
 var v7 = function(){};

148.你如何定义 JSON 数组?

JSON 数组写在方括号内,数组包含 javascript 对象。例如,用户的 JSON 数组如下所示,

 "users":[
   {"firstName":"Haiyong", "lastName":"Abrahm"},
   {"firstName":"Anna", "lastName":"Smith"},
   {"firstName":"Shane", "lastName":"Warn"}
 ]

149.你如何生成随机整数?

您可以使用 Math.random() 和 Math.floor() 来返回随机整数。例如,如果要生成 1 到 10 之间的随机整数,则乘法因子应为 10,

 Math.floor(Math.random() * 10) + 1;     // 返回一个从 1 到 10 的随机整数
 Math.floor(Math.random() * 100) + 1;     // 返回一个从 1 到 100 的随机整数

注意: Math.random() 返回一个介于 0(含)和 1(不含)之间的随机数


150.你能写一个随机整数函数来打印范围内的整数吗?

是的,您可以创建一个适当的随机函数来返回一个介于 min 和 max 之间的随机数(均包括在内)

 function randomInteger(min, max) {
   return Math.floor(Math.random() * (max - min + 1) ) + min;
 }
 randomInteger(1, 100); // 返回一个从 1 到 100 的随机整数
 randomInteger(1, 1000); // 返回一个从 1 到 1000 的随机整数

151.什么是tree shaking(摇树)?

tree shaking(摇树)是消除死代码的一种形式。这意味着在构建过程中未使用的模块不会包含在包中,因此它依赖于 ES2015 模块语法的静态结构,(即导入和导出)。最初这已被 ES2015 模块捆绑器推广rollup。


152.tree shaking(摇树)需要什么?

Tree Shaking 可以显着减少任何应用程序中的代码大小。即,我们通过网络发送的代码越少,应用程序的性能就越高。例如,如果我们只想使用 SPA 框架创建一个“Hello World”应用程序,那么它大约需要几 MB,但是通过 treeShaking,它可以将大小降低到几百 KB。摇树在 Rollup 和 Webpack 打包器中实现。


153.是否推荐使用 eval?

不推荐,它允许运行导致安全问题的任意代码。我们知道 eval() 函数用于将文本作为代码运行。在大多数情况下,应该没有必要使用它。


154.什么是正则表达式?

正则表达式是形成搜索模式的字符序列。您可以使用此搜索模式在文本中搜索数据。这些可用于执行所有类型的文本搜索和文本替换操作。现在让我们看看语法格式,

 /pattern/modifiers;

例如,用户名不区分大小写的正则表达式或搜索模式是,

 /Haiyong/i

可以看看作者对正则表达式的总结:https://haiyong.blog.csdn.net/article/details/114939060


155.正则表达式中可用的字符串方法有哪些?

正则表达式有两个字符串方法:search() 和 replace()。
search() 方法使用表达式来搜索匹配项,并返回匹配项的位置。

 var msg = "Hello Haiyong";
 var n = msg.search(/Haiyong/i); // 6

replace() 方法用于返回已替换模式的修改后的字符串。

 var msg = "Hello Haiyong";
 var n = msg.replace(/Haiyong/i, "Buttler"); // Hello Buttler

156.正则表达式中的修饰符是什么?

修饰符可用于执行不区分大小写的全局搜索。让我们列出一些修饰符,

修饰符说明
i (ignore)执行不区分大小写的匹配
g (global)执行全局匹配而不是在第一次匹配时停止
m (more)执行多行匹配

让我们举一个全局修饰符的例子,

  var text = "Learn JS one by one";
  var pattern = /one/g;
  var result = text.match(pattern); // one,one

157.什么是正则表达式模式?

正则表达式提供一组模式以匹配字符。基本上它们分为3种类型,

1.括号:这些用于查找一系列字符。例如,下面是一些用例,

  • [abc]:用于查找括号(a,b,c)之间的任何字符

  • [0-9]:用于查找括号之间的任何数字

  • (a|b):用于查找以 | 分隔的任何选项

2.元字符:这些是具有特殊含义的字符例如,以下是一些用例,

  • \d:用于查找数字

  • \s:用于查找空白字符

  • \b:用于在单词的开头或结尾查找匹配项

3.量词:这些对于定义量很有用,例如,下面是一些用例,

  • n+:用于查找任何包含至少一个 n 的字符串的匹配项

  • n*:用于查找包含零次或多次出现的 n 的任何字符串的匹配项

  • n?:用于查找包含零次或一次 n 的任何字符串的匹配项


158.什么是 RegExp 对象?

RegExp 对象是一个具有预定义属性和方法的正则表达式对象。下面来看看 RegExp 对象的简单用法,

 var regexp = new RegExp('\\w+');
 console.log(regexp);
 // 预期输出: /\w+/

159.如何在字符串中搜索模式?

您可以使用正则表达式的 test() 方法来搜索字符串中的模式,并根据结果返回 true 或 false。

 var pattern = /you/;
 console.log(pattern.test("How are you?")); //true

160.exec方法的目的是什么?

exec 方法的目的类似于 test 方法,但它执行搜索指定字符串中的匹配项并返回结果数组,或者 null 而不是返回 true/false。

 var pattern = /you/;
 console.log(pattern.exec("How are you?")); //["you", index: 8, 输出: "How are you?", groups: 未定义]

161.如何更改 HTML 元素的样式?

您可以使用 javascript 更改 HTML 元素的内联样式或类名

使用样式属性:您可以使用样式属性修改内联样式

 document.getElementById("title").style.fontSize = "30px";

使用 ClassName 属性:使用 className 属性很容易修改元素类

  document.getElementById("title").className = "custom-title";

162.1+2+'3’ 的结果是什么?

输出将是33. 由于1和2是数值,前两位数字的结果将是数值3。下一个数字是字符串类型值,因为数值3和字符串类型值3的相加只是一个串联值33。


163.什么是调试器语句?

调试器语句调用任何可用的调试功能,例如设置断点。如果没有可用的调试功能,则此语句无效。

例如,在下面的函数中插入了一个调试器语句。因此,
执行在调试器语句处暂停,就像脚本源中的断点一样。

 function getProfile() {
 // 代码在这里
 debugger;
 // 代码在这里
 }

164.调试中断点的目的是什么?

一旦执行调试器语句并弹出调试器窗口,您就可以在 javascript 代码中设置断点。在每个断点处,javascript 将停止执行,并让您检查 JavaScript 值。检查值后,您可以使用播放按钮恢复代码的执行。


165.我可以使用保留字作为标识符吗?

不,您不能将保留字用作变量、标签、对象或函数名称。让我们看一个简单的例子,

 var else = "hello"; // 未捕获的 SyntaxError: 意外的标记 else

166.你如何检测移动浏览器?

您可以使用正则表达式,它会根据用户是否使用手机浏览来返回 true 或 false 值。

 window.mobilecheck = function() {
   var mobileCheck = false;
   (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))) mobileCheck = true;})(navigator.userAgent||navigator.vendor||window.opera);
   return mobileCheck;
 };

167.如何在没有正则表达式的情况下检测移动浏览器?

您可以通过简单地运行设备列表并检查用户代理是否匹配任何内容来检测移动浏览器。这是 RegExp 使用的替代解决方案,

 function detectmob() {
  if( navigator.userAgent.match(/Android/i)
  || navigator.userAgent.match(/webOS/i)
  || navigator.userAgent.match(/iPhone/i)
  || navigator.userAgent.match(/iPad/i)
  || navigator.userAgent.match(/iPod/i)
  || navigator.userAgent.match(/BlackBerry/i)
  || navigator.userAgent.match(/Windows Phone/i)
  ){
     return true;
   }
  else {
     return false;
   }
 }

168.你如何使用JS获取图像的宽度和高度?

您可以使用 Javascript 以编程方式获取图像并检查尺寸(宽度和高度)。

 var img = new Image();
 img.onload = function() {
   console.log(this.width + 'x' + this.height);
 }
 img.src = 'https://img-blog./20210427214255127.png';

169.如何进行同步 HTTP 请求?

浏览器提供了一个 XMLHttpRequest 对象,可用于从 JavaScript 发出同步 HTTP 请求

 function httpGet(theUrl)
 {
     var xmlHttpReq = new XMLHttpRequest();
     xmlHttpReq.open( "GET", theUrl, false ); // 同步请求为 false
     xmlHttpReq.send( null );
     return xmlHttpReq.responseText;
 }

170.如何进行异步 HTTP 请求?

浏览器提供了一个 XMLHttpRequest 对象,该对象可用于通过将第三个参数传递为 true 来从 JavaScript 发出异步 HTTP 请求。

 function httpGetAsync(theUrl, callback)
 {
     var xmlHttpReq = new XMLHttpRequest();
     xmlHttpReq.onreadystatechange = function() {
         if (xmlHttpReq.readyState == 4 && xmlHttpReq.status == 200)
             callback(xmlHttpReq.responseText);
     }
     xmlHttp.open("GET", theUrl, true); // 异步为 true
     xmlHttp.send(null);
 }

171.你如何在javascript中将日期转换为另一个时区?

您可以使用 toLocaleString() 方法将一个时区中的日期转换为另一个时区。例如,让我们将当前日期转换为英式英语时区,如下所示,

 console.log(event.toLocaleString('en-GB', { timeZone: 'UTC' })); //21/06/2021, 08:00:00

172.用于获取窗口大小的属性是什么?

您可以使用窗口、文档元素和文档正文对象的innerWidth、innerHeight、clientWidth、clientHeight 属性来查找窗口的大小。让我们使用这些属性的组合来计算窗口或文档的大小,

 var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;

 var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

173.什么是javascript中的条件运算符?

条件(三元)运算符是唯一的 JavaScript 运算符,它采用三个操作数作为 if 语句的快捷方式。

 var isAuthenticated = false;
 console.log(isAuthenticated ? 'Hello, welcome' : 'Sorry, you are not authenticated');//Sorry, you are not authenticated

174.你能在条件运算符上应用chaining吗?

是的,您可以在条件运算符上应用chaining,类似于 if … else if … else if … else 链。语法如下,

 function traceValue(someParam) {
     return condition1 ? value1          : condition2 ? value2          : condition3 ? value3          : value4;
 }

 // 上述条件运算符等价于:

 function traceValue(someParam) {
     if (condition1) { return value1; }
     else if (condition2) { return value2; }
     else if (condition3) { return value3; }
     else { return value4; }
 }

175.页面加载后执行javascript的方式有哪些?

您可以在页面加载后以多种不同方式执行 javascript,

窗口.onload:

 window.onload = function ...

文件加载:

 document.onload = function ...

身体加载:

 <body onload="script();">

176.proto 和 prototype有什么区别?

__proto__对象是在查找链中用于解析方法等的实际对象。而当您使用 new 创建对象时prototype,用于构建__proto__的对象是

 ( new Employee ).__proto__ === Employee.prototype;
 ( new Employee ).prototype === undefined;

177.举个例子你最好使用分号

建议在 JavaScript 中的每个语句后使用分号。例如,在下面的情况下,由于缺少分号,它在运行时会抛出错误“… is not a function”。

 // 定义一个函数
 var fn = function () {
     //...
 } // 此行缺少分号
 // 然后在闭包中执行一些代码
 (function () {
     //...
 })();

它将被解释为

 var fn = function () {
     //...
 }(function () {
     //...
 })();

在这种情况下,我们将第二个函数作为参数传递给第一个函数,然后尝试将第一个函数调用的结果作为函数调用。因此,第二个函数将在运行时因“…不是函数”错误而失败。


178.什么是freeze 方法?

reeze()方法用于冻结对象。冻结对象不允许向对象添加新属性,阻止删除和阻止更改现有属性的可枚举性、可配置性或可写性。即,它返回传递的对象并且不创建冻结副本。

const obj = {
   prop: 100
 };

 Object.freeze(obj);
 obj.prop = 200; // 在严格模式下抛出错误

 console.log(obj.prop); //100

注意:如果传递的参数不是对象,则会导致 TypeError。


179.freeze 方法的目的是什么?

以下是使用冻结方法的主要好处,

1.它用于冻结对象和数组。
2.它用于使对象不可变。


180.为什么我需要使用freeze 方法?

在面向对象的范式中,现有 API 包含某些不打算在当前上下文之外扩展、修改或重用的元素。因此,它final用作各种语言中使用的关键字。


181.你如何检测浏览器语言首选项?

您可以使用导航器对象来检测浏览器语言首选项,如下所示,

 var language = navigator.languages && navigator.languages[0] || // Chrome / Firefox
                navigator.language ||   // All browsers
                navigator.userLanguage; // IE <= 10

 console.log(language);

182.如何使用javascript将字符串转换为标题大小写?

标题大小写意味着每个单词的第一个字母大写。您可以使用以下函数将字符串转换为标题大小写,

 function toTitleCase(str) {
     return str.replace(
         /\w\S*/g,
         function(txt) {
             return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
         }
     );
 }
 toTitleCase("good morning csdn"); // Good Morning Csdn

183.你如何检测页面中禁用的javascript?

您可以使用该标签来检测 javascript 是否禁用。当 JavaScript 被禁用时,里面的代码块会被执行,并且通常用于在 JavaScript 生成页面时显示替代内容。

 <script type="javascript">
     // JS相关代码放这里
 </script>
 <noscript>
     <a href="next_page.html?noJS=true">JavaScript is disabled in the page. Please click Next Page</a>
 </noscript>

184.javascript支持的各种运算符有哪些?

运算符能够操纵(数学和逻辑计算)某个值或操作数。JavaScript 支持的各种运算符如下,

  • 算术运算符:包括 +(加法)、–(减法)、*(乘法)、/(除法)、%(模数)、++(增量)和 – –(减量)

  • 比较运算符:包括 ==(等于)、!=(不等于)、===(与类型相等)、>(大于)、>=(大于或等于)、<(小于)、<= (小于或等于)

  • 逻辑运算符:包括 &&(逻辑与)、||(逻辑或)、!(逻辑非)

  • 赋值运算符:包括 =(赋值运算符)、+=(加法和赋值运算符)、–=(减法和赋值运算符)、*=(乘法和赋值)、/=(除法和赋值)、%=(模块和赋值) )

  • 三元运算符:它包括条件(:?)运算符

  • typeof 运算符:用于查找变量的类型。语法看起来像typeof variable


185.什么是rest 参数?

Rest 参数是一种处理函数参数的改进方法,它允许我们将无限数量的参数表示为数组。语法如下,

 function f(a, b, ...theArgs) {
   // ...
 }

例如,让我们举一个 sum 示例来计算动态参数数量,

 function total(…args){
 let sum = 0;
 for(let i of args){
 sum+=i;
 }
 return sum;
 }
 console.log(fun(1,2)); //3
 console.log(fun(1,2,3)); //6
 console.log(fun(1,2,3,4)); //13
 console.log(fun(1,2,3,4,5)); //15

注意:在 ES2015 或 ES6 中添加了 Rest 参数


186.如果不使用 rest 参数作为最后一个参数会发生什么?

rest 参数应该是最后一个参数,因为它的工作是将所有剩余的参数收集到一个数组中。例如,如果你定义一个像下面这样的函数,它没有任何意义并且会抛出一个错误。

 function someFunc(a,…b,c){
 //你的代码在这里
 return;
 }

187.什么是 JavaScript 中可用的按位运算符?

下面是 JavaScript 中使用的按位逻辑运算符列表

1.按位与 ( & )
2.按位或 ( | )
3.按位异或 (^)
4.按位非 ( ~ )
5.左移 (<<)
6.符号传播右移 ( >> )
7.零填充右移 ( >>> )


188.什么是spread operator(展开运算符)?

展开运算符允许将可迭代对象(数组/对象/字符串)扩展为单个参数/元素。让我们举个例子来看看这个行为,

 function calculateSum(x, y, z) {
   return x + y + z;
 }

 const numbers = [1, 2, 3];

 console.log(calculateSum(...numbers)); // 6

189.你如何确定对象是否被冻结?

Object.isFrozen() 方法用于确定对象是否被冻结。如果以下所有条件都成立,则对象被冻结,

1.如果不能扩展。
2.如果它的所有属性都是不可配置的。
3.如果它的所有数据属性都是不可写的。用法如下,

 const object = {
    property: 'Welcome JS world'
 };
 Object.freeze(object);
 console.log(Object.isFrozen(object));

190.你如何确定两个值相同或不使用对象?

Object.is() 方法确定两个值是否相同。例如,不同类型值的用法是,

 Object.is('hello', 'hello');     // true
 Object.is(window, window);   // true
 Object.is([], []) // false

如果以下条件之一成立,则两个值相同:

1.两者都未定义
2.都为空
3.都是真的还是假的
4.相同长度的两个字符串以相同的顺序具有相同的字符
5.两个相同的对象(意味着两个对象具有相同的引用)
6.两个数字和两个 +0 两个 -0 两个 NaN 都是非零和都不是 NaN 并且两者都具有相同的值。


191.使用Object 的 is方法的目的是什么?

Object 的 is 方法的一些应用如下,

1.它用于比较两个字符串。
2.它用于比较两个数字。
3.它用于比较两个数字的极性。
4.它用于比较两个对象。


192.如何将属性从一个对象复制到另一个对象?

您可以使用 Object.assign() 方法将值和属性从一个或多个源对象复制到目标对象。它返回具有从目标对象复制的属性和值的目标对象。语法如下,

 Object.assign(target, ...sources)

让我们以一个源和一个目标对象为例,

 const target = { a: 1, b: 2 };
 const source = { b: 3, c: 4 };
 const returnedTarget = Object.assign(target, source);
 console.log(target); // { a: 1, b: 3, c: 4 }
 console.log(returnedTarget); // { a: 1, b: 3, c: 4 }

正如在上面的代码中所观察到的,b从源到目标有一个共同的 property( ),因此它的值已被覆盖。


193.赋值方法有哪些应用?

下面是 Object.assign() 方法的一些主要应用,

  • 它用于克隆对象。

  • 它用于合并具有相同属性的对象。


194.什么是Proxy(代理)对象?

Proxy 对象用于定义基本操作的自定义行为,例如属性查找、赋值、枚举、函数调用等。语法如下:

 var p = new Proxy(target, handler);

让我们以代理对象为例,

 var handler = {
     get: function(obj, prop) {
         return prop in obj ?
             obj[prop] :
             100;
     }
 };

 var p = new Proxy({}, handler);
 p.a = 10;
 p.b = null;

 console.log(p.a, p.b); // 10, null
 console.log('c' in p, p.c); // false, 100

在上面的代码中,它使用get处理程序定义代理在其上执行操作时的行为


195.seal 方法的目的是什么?

所述Object.seal()方法被用于密封一个对象,通过防止从被添加到它的新属性和标记所有现有的性质不可配置的。但是当前属性的值仍然可以更改,只要它们是可写的。让我们看下面的例子来了解更多关于 Seal() 方法的信息

  const object = {
     property: 'Welcome JS world'
  };
  Object.seal(object);
  object.property = 'Welcome to object world';
  console.log(Object.isSealed(object)); // true
  delete object.property; // You cannot delete when sealed
  console.log(object.property); //Welcome to object world

196.seal 方法的应用有哪些?

下面是 Object.seal() 方法的主要应用,

  • 它用于密封对象和数组。

  • 它用于使对象不可变。


197.freeze 和 seal 方法有什么区别?

如果使用 Object.freeze() 方法冻结对象,则其属性将变为不可变且无法对其进行更改,而如果使用 Object.seal() 方法密封对象,则可以在现有属性中进行更改的对象。


198.如何判断物体是否 seal?

Object.isSealed() 方法用于确定对象是否已密封。如果以下所有条件都成立,则对象被密封

1.如果不能扩展。
2.如果它的所有属性都是不可配置的。
3.如果它不可移动(但不一定不可写)。让我们在行动中看到它

 const object = {
 property: 'Hello, Good morning'
 };

 Object.seal(object); // 使用 Seal() 方法密封对象

 console.log(Object.isSealed(object));      // 检查对象是否密封

199.如何获得可枚举的键值对?

Object.entries() 方法用于返回给定对象自己的可枚举字符串键控属性 [key, value] 对的数组,其顺序与 for…in 循环提供的顺序相同。让我们在一个例子中看看 object.entries() 方法的功能,

 const object = {
   a: 'Good morning',
   b: 100
 };

 for (let [key, value] of Object.entries(object)) {
   console.log(`${key}: ${value}`); // a: 'Good morning'
                                    // b: 100
 }

注意:顺序不保证为对象定义。


200.Object.values 和 Object.entries 方法的主要区别是什么?

Object.values() 方法的行为类似于 Object.entries() 方法,但它返回一个值数组而不是 [key,value] 对。

  const object = {
    a: 'Good morning',
    b: 100
  };

  for (let value of Object.values(object)) {
    console.log(`${value}`); // 'Good morning'
                                 100
  }

201.如何获取任何对象的键列表?

您可以使用Object.keys()用于返回给定对象自己的属性名称的数组的方法,其顺序与我们使用普通循环获得的顺序相同。例如,您可以获取用户对象的键,

 const user = {
   name: 'Haiyong',
   gender: 'male',
   age: 40
 };

 console.log(Object.keys(user)); //['name', 'gender', 'age']

202.你如何用 prototype 创建一个对象?

Object.create() 方法用于创建具有指定原型对象和属性的新对象。即,它使用现有对象作为新创建对象的原型。它返回一个具有指定原型对象和属性的新对象。

  const user = {
    name: 'Haiyong',
    printInfo: function () {
      console.log(`My name is ${this.name}.`);
    }
  };

  const admin = Object.create(user);

  admin.name = "Nick"; //请记住,"name"是在"admin"而非"user"对象上设置的属性

  admin.printInfo(); // My name is Nick

203.什么是WeakSet?

WeakSet 用于存储弱(弱引用)持有对象的集合。语法如下,

 new WeakSet([iterable]);

让我们看下面的例子来解释它的行为,

 var ws = new WeakSet();
 var user = {};
 ws.add(user);
 ws.has(user);    // true
 ws.delete(user); // 从集合中删除user
 ws.has(user);    // false, user 已被删除

204.WeakSet 和 Set 有什么区别?

主要区别在于 Set 中对象的引用是强引用,而 WeakSet 中对象的引用是弱引用。即,如果没有其他引用 WeakSet 中的对象可以被垃圾回收。

其他区别是,

1.Sets 可以存储任何值而 WeakSets 只能存储对象的集合
2.WeakSet 没有与 Set 不同的 size 属性
3.WeakSet 没有 clear、keys、values、entries、forEach 等方法。
4.WeakSet 不可迭代。


205.列出 WeakSet 上可用的方法集合?

下面是 WeakSet 上可用的方法列表,

1.add(value):将给定值附加到弱集的新对象
2.delete(value):从 WeakSet 集合中删除值。
3.has(value):如果 WeakSet 集合中存在该值,则返回 true,否则返回 false。
4.length():它返回weakSetObject的长度让我们在一个例子中看看上述所有方法的功能,

 var weakSetObject = new WeakSet();
 var firstObject = {};
 var secondObject = {};
 // add(value)
 weakSetObject.add(firstObject);
 weakSetObject.add(secondObject);
 console.log(weakSetObject.has(firstObject)); //true
 console.log(weakSetObject.length()); //2
 weakSetObject.delete(secondObject);

206.什么是 WeakMap?

WeakMap 对象是键/值对的集合,其中的键被弱引用。在这种情况下,键必须是对象,值可以是任意值。语法如下所示,

 new WeakMap([iterable])

让我们看下面的例子来解释它的行为,

  var ws = new WeakMap();
  var user = {};
  ws.set(user);
  ws.has(user);    // true
  ws.delete(user); // 从 map 中删除用户
  ws.has(user);    // false, user 已被删除

207.WeakMap 和 Map 有什么区别?

主要区别在于 Map 中关键对象的引用是强引用,而 WeakMap 中关键对象的引用是弱引用。即,如果没有其他引用 WeakMap 中的键对象可以被垃圾收集。

其他区别是,

1.Maps 可以存储任何类型的键,而 WeakMaps 只能存储键对象的集合
2.与 Map 不同,WeakMap 没有 size 属性
3.WeakMap 没有 clear、keys、values、entries、forEach 等方法。
4.WeakMap 不可迭代。


208.列出 WeakMap 上可用的方法集合?

下面是 WeakMap 上可用的方法列表,

1.set(key, value):设置 WeakMap 对象中键的值。返回 WeakMap 对象。
2.delete(key):删除与键关联的任何值。
3.has(key):返回一个布尔值,断言一个值是否与 WeakMap 对象中的键相关联。
4.get(key):返回与键关联的值,如果没有则返回 undefined。让我们在一个例子中看看上述所有方法的功能,

 var weakMapObject = new WeakMap();
 var firstObject = {};
 var secondObject = {};
 // set(key, value)
 weakMapObject.set(firstObject, 'Haiyong');
 weakMapObject.set(secondObject, 100);
 console.log(weakMapObject.has(firstObject)); //true
 console.log(weakMapObject.get(firstObject)); // Haiyong
 weakMapObject.delete(secondObject);

209.uneval 的目的是什么?

uneval() 是一个内置函数,用于创建对象源代码的字符串表示。它是一个顶级函数,不与任何对象相关联。让我们看下面的例子来了解更多关于它的功能,

 var a = 1;
 uneval(a); // 返回一个包含 1 的字符串
 uneval(function user() {}); // returns "(function user(){})"

210.你如何 encode (编码)一个 URL?

encodeURI() 函数用于对除 (, / ? : @ & = + $ #) 字符外具有特殊字符的完整 URI 进行编码。

 var uri = 'https://mozilla.org/?x=шеллы';
 var encoded = encodeURI(uri);
 console.log(encoded); // https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B

211.你如何 decode (解码)一个 URL?

decodeURI() 函数用于解码之前由 encodeURI() 创建的统一资源标识符 (URI)。

  var uri = 'https://mozilla.org/?x=шеллы';
  var encoded = encodeURI(uri);
  console.log(encoded); // https://mozilla.org/?x=%D1%88%D0%B5%D0%BB%D0%BB%D1%8B
 try {
   console.log(decodeURI(encoded)); // "https://mozilla.org/?x=шеллы"
 } catch(e) { // 捕获格式错误的 URI
   console.error(e);
 }

212.你如何打印网页的内容?

window 对象提供了一个 print() 方法,用于打印当前窗口的内容。它会打开一个打印对话框,让您在各种打印选项之间进行选择。让我们在一个例子中看看print方法的用法,

<input type="button" value="Print" onclick="window.print()" />

注意:在大多数浏览器中,它会在打印对话框打开时被阻止。


213.uneval 和 eval 有什么区别?

该uneval函数返回给定对象的来源;而该eval函数则相反,通过评估不同内存区域中的源代码。让我们看一个例子来澄清差异,

 var msg = uneval(function greeting() { return 'Hello, Good morning'; });
 var greeting = eval(msg);
 greeting(); // returns "Hello, Good morning"

214.什么是 anonymous (匿名)函数?

匿名函数就是没有名字的函数!匿名函数通常分配给变量名称或用作回调函数。语法如下,

 function (optionalParameters) {
   //do something
 }

 const myFunction = function(){ //分配给变量的匿名函数
   //do something
 };

 [1, 2, 3].map(function(element){ //匿名函数用作回调函数
   //do something
 });

让我们在一个例子中看看上面的匿名函数,

 var x = function (a, b) {return a * b};
 var z = x(5, 10);
 console.log(z); // 50

215.局部变量和全局变量的优先顺序是什么?

局部变量优先于同名的全局变量。让我们在一个例子中看看这种行为。

 var msg = "Good morning";
 function greeting() {
    msg = "Good Evening";
    console.log(msg);
 }
 greeting();

216.什么是 javascript 访问器?

ECMAScript 5 通过 getter 和 setter 引入了 javascript 对象访问器或计算属性。Getters 使用get关键字,而 Setters 使用set关键字。

 var user = {
   firstName: "Hai",
   lastName : "Yong",
   language : "cn",
   get lang() {
     return this.language;
   }
   set lang(lang) {
   this.language = lang;
   }
 };
 console.log(user.lang); // getter 访问 lang as cn
 user.lang = 'en';
 console.log(user.lang); // setter 用于将 lang 设置为 en

217.你如何在对象构造函数上定义属性?

Object.defineProperty() 静态方法用于直接在对象上定义新属性,或修改对象上现有的属性,并返回该对象。让我们看一个例子来了解如何定义属性,

 const newObject = {};

 Object.defineProperty(newObject, 'newProperty', {
   value: 100,
   writable: false
 });

 console.log(newObject.newProperty); // 100

 newObject.newProperty = 200; // 由于可写设置,它在严格模式下抛出错误

218.get 和defineProperty 有什么区别?

除非您使用类,否则两者都有相似的结果。如果您使用get该属性将在对象的原型上定义,而使用Object.defineProperty()该属性将在它应用到的实例上定义。


219.Getter 和 Setter 的优点是什么?

以下是 Getter 和 Setter 的好处列表,

1.它们提供更简单的语法
2.它们用于定义计算属性或 JS 中的访问器。
3.用于提供属性和方法之间的等价关系
4.他们可以提供更好的数据质量
5.对于使用封装的逻辑在幕后做事很有用。


220.我可以使用defineProperty方法添加 getter 和 setter 吗?

是的,您可以使用该Object.defineProperty()方法添加 Getter 和 Setter。例如,下面的计数器对象使用递增、递减、加减属性,

 var obj = {counter : 0};

 // Define getters
 Object.defineProperty(obj, "increment", {
   get : function () {this.counter++;}
 });
 Object.defineProperty(obj, "decrement", {
   get : function () {this.counter--;}
 });

 // Define setters
 Object.defineProperty(obj, "add", {
   set : function (value) {this.counter += value;}
 });
 Object.defineProperty(obj, "subtract", {
   set : function (value) {this.counter -= value;}
 });

 obj.add = 10;
 obj.subtract = 5;
 console.log(obj.increment); //6
 console.log(obj.decrement); //5

221.switch-case 的目的是什么?

JavaScript 中的 switch case 语句用于决策目的。在某些情况下,使用 switch case 语句会比 if-else 语句更方便。语法如下,

 switch ()
 {
     case value1:
         statement1;
         break;
     case value2:
         statement2;
         break;
     .
     .
     case valueN:
         statementN;
         break;
     default:
         statementDefault;
 }

上面的多路分支语句提供了一种简单的方法,可以根据表达式的值将执行分派到代码的不同部分。


222.使用 swtich case 需要遵循什么规定?

以下是应注意的规定列表,

1.表达式可以是数字或字符串类型。
2.表达式不允许重复值。
3.默认语句是可选的。如果传递给 switch 的表达式与任何 case 值都不匹配,则将执行 default case 中的语句。
4.break 语句在 switch 中用于终止语句序列。
5.break 语句是可选的。但如果省略,执行将继续到下一个案例。


223.什么是原始数据类型?

原始数据类型是具有原始值(没有属性或方法)的数据。有 7 种原始数据类型。

1.string
2.number
3.boolean
4.null
5.undefined
6.bigint
7.symbol


224.访问对象属性的不同方式有哪些?

有 3 种可能的方法来访问对象的属性。

点符号:它使用点来访问属性

 objectName.property

方括号表示法:它使用方括号进行属性访问

 objectName["property"]

表达式符号:它使用方括号中的表达式

 objectName[]

225.什么是函数参数规则?

JavaScript 函数遵循以下参数规则,

1.函数定义不指定参数的数据类型。
2.不要对传递的参数执行类型检查。
3.不要检查收到的参数数量。即,以下函数遵循上述规则,

 function functionName(parameter1, parameter2, parameter3) {
   console.log(parameter1); // 1
 }
 functionName(1);

226.什么是错误对象?

错误对象是一个内置的错误对象,它在发生错误时提供错误信息。它有两个属性:名称和消息。例如,以下函数记录错误详细信息,

 try {
   greeting("Welcome");
 }
 catch(err) {
   console.log(err.name + "<br>" + err.message);
 }

227.当你收到语法错误时

如果您尝试评估具有语法错误的代码,则会引发 SyntaxError。例如,下面缺少的函数参数引用会引发语法错误

 try {
   eval("greeting('welcome)");   // Missing ' will produce an error
 }
 catch(err) {
   console.log(err.name);
 }

228.错误对象有哪些不同的错误名称?

错误对象返回了 6 种不同类型的错误名称,

错误名称说明
EvalErroreval() 函数发生错误
RangeError数字“超出范围”发生错误
ReferenceError由于非法引用而导致的错误
SyntaxError语法错误导致的错误
TypeError类型错误导致的错误
URIError由于 encodeURI() 导致的错误

229.错误处理中的各种语句是什么?

以下是错误处理中使用的语句列表,

1.try:该语句用于测试代码块是否有错误
2.catch:该语句用于处理错误
3.throw:此语句用于创建自定义错误。
4.finally:该语句用于在 try 和 catch 之后执行代码,而不管结果如何。


230.javascript中的两种类型的循环是什么?

1.进入Controlled Loops受控循环:在这种循环类型中,在进入循环体之前测试测试条件。例如,For 循环和 While 循环就属于这一类。

2.退出 Controlled Loops:在这种循环类型中,测试条件在循环体的末尾进行测试或评估。即,无论测试条件为真还是假,循环体都将至少执行一次。例如,do-while 循环就属于这一类。


231.什么是 nodejs?

Node.js 是一个基于 Chrome 的 JavaScript 运行时构建的服务器端平台,用于轻松构建快速且可扩展的网络应用程序。它是一个基于事件的、非阻塞的、异步的 I/O 运行时,使用谷歌的 V8 JavaScript 引擎和 libuv 库。


232.什么是 Intl 对象?

Intl 对象是 ECMAScript 国际化 API 的命名空间,它提供语言敏感的字符串比较、数字格式以及日期和时间格式。它提供对几个构造函数和语言敏感函数的访问。


233.你如何执行特定于语言的日期和时间格式化?

您可以使用Intl.DateTimeFormat对象,它是启用语言敏感日期和时间格式的对象的构造函数。让我们用一个例子来看看这个行为,

 var date = new Date(Date.UTC(2019, 07, 07, 3, 0, 0));
 console.log(new Intl.DateTimeFormat('en-GB').format(date)); // 07/08/2019
 console.log(new Intl.DateTimeFormat('en-AU').format(date)); // 07/08/2019

234.什么是迭代器?

迭代器是一个对象,它在终止时定义一个序列和一个返回值。它使用一个next()方法实现迭代器协议,该方法返回一个具有两个属性的对象:(value序列中的下一个值)和done(如果序列中的最后一个值已被消耗,则为真)。


235.同步迭代是如何工作的?

ES6 中引入了同步迭代,它适用于以下组件集,

Iterable:它是一个可以通过其键为 Symbol.iterator 的方法迭代的对象。
迭代器:它是通过调用[Symbol.iterator]()可迭代对象返回的对象。这个迭代器对象将每个迭代的元素包装在一个对象中,并通过next()方法一一返回。
IteratorResultnext()方法返回的对象。该对象包含两个属性;该value属性包含一个迭代元素,该done属性确定该元素是否是最后一个元素。

让我们用下面的数组演示同步迭代,

 const iterable = ['one', 'two', 'three'];
 const iterator = iterable[Symbol.iterator]();
 console.log(iterator.next());  // { value: 'one', done: false }
 console.log(iterator.next());  // { value: 'two', done: false }
 console.log(iterator.next());  // { value: 'three', done: false }
 console.log(iterator.next());  // { value: 'undefined, done: true }

236.什么是事件循环?

事件循环是一个回调函数队列。当异步函数执行时,回调函数被推入队列。JavaScript 引擎在异步函数执行完代码之前不会开始处理事件循环。

注意:即使 JavaScript 是单线程的,它也允许 Node.js 执行非阻塞 I/O 操作。


237.什么是调用栈?

调用堆栈是 javascript 解释器的一种数据结构,用于跟踪程序中的函数调用。它有两个主要动作,

1.每当你调用一个函数来执行它时,你就是在将它压入堆栈。
2.每当执行完成时,函数就会从堆栈中弹出。

让我们举个例子,它是图表格式的状态表示

 function hungry() {
    eatFruits();
 }
 function eatFruits() {
    return "I'm eating fruits";
 }

 // Invoke the `hungry` function
 hungry();

上面的代码在调用堆栈中处理如下,

1.将hungry()函数添加到调用堆栈列表并执行代码。
2.将eatFruits()函数添加到调用堆栈列表并执行代码。
3.eatFruits()从我们的调用堆栈列表中删除该函数。
4.hungry()从调用堆栈列表中删除该函数,因为不再有项目。


238.什么是事件队列?

对消息或事件的发送与处理进行时间上的解耦。通俗地讲就是在队列中按先入先出的顺序存储一系列通知或请求。 发送通知时,将请求放入队列并返回。 处理请求的系统之后稍晚从队列中获取请求并处理。


239.什么是装饰器?

装饰器是一个表达式,其计算结果为函数,并将目标、名称和装饰器描述符作为参数。此外,它还可以选择返回一个装饰器描述符以安装在目标对象上。让我们在设计时为用户类定义管理装饰器,

 function admin(isAdmin) {
    return function(target) {
        target.isAdmin = isAdmin;
    }
 }

 @admin(true)
 class User() {
 }
 console.log(User.isAdmin); //true

  @admin(false)
  class User() {
  }
  console.log(User.isAdmin); //false

240.Intl 对象的属性是什么?

以下是 Intl 对象上可用的属性列表,

1.Collator:这些是启用对语言敏感的字符串比较的对象。
2.DateTimeFormat:这些是启用对语言敏感的日期和时间格式的对象。
3.ListFormat:这些是启用语言敏感列表格式的对象。
4.NumberFormat:启用对语言敏感的数字格式的对象。
5.PluralRules:启用复数敏感格式和复数语言特定规则的对象。
6.RelativeTimeFormat:启用对语言敏感的相对时间格式的对象。


241.什么是一元运算符?

一元(+)运算符用于将变量转换为数字。如果变量无法转换,它仍然会变成数字,但值为 NaN。让我们在一个动作中看看这个行为。

 var x = "100";
 var y = + x;
 console.log(typeof x, typeof y); // string, number

 var a = "Hello";
 var b = + a;
 console.log(typeof a, typeof b, b); // string, number, NaN

242.如何对数组中的元素进行排序?

sort() 方法用于对数组元素进行原地排序并返回排序后的数组。示例用法如下,

 var months = ["Aug", "Sep", "Jan", "June"];
 months.sort();
 console.log(months); //  ["Aug", "Jan", "June", "Sep"]

243.排序数组时 compareFunction 的目的是什么?

compareFunction 用于定义排序顺序。如果省略,数组元素将转换为字符串,然后根据每个字符的 Unicode 代码点值进行排序。举个例子来看看compareFunction的用法,

 let numbers = [1, 2, 5, 3, 4];
 numbers.sort((a, b) => b - a);
 console.log(numbers); // [5, 4, 3, 2, 1]

244.你如何反转数组?

您可以使用 reverse() 方法来反转数组中的元素。此方法对于按降序对数组进行排序很有用。让我们在一个例子中看看 reverse() 方法的用法,

 let numbers = [1, 2, 5, 3, 4];
 numbers.sort((a, b) => b - a);
 numbers.reverse();
 console.log(numbers); // [1, 2, 3, 4 ,5]

245.你如何在数组中找到最小值和最大值?

您可以对数组变量使用Math.minMath.max方法来查找数组中的最小和最大元素。让我们创建两个函数来查找数组中的最小值和最大值,

 var marks = [50, 20, 70, 60, 45, 30];
 function findMin(arr) {
   return Math.min.apply(null, arr);
 }
 function findMax(arr) {
   return Math.max.apply(null, arr);
 }

 console.log(findMin(marks));
 console.log(findMax(marks));

246.如何在没有math函数的情况下找到最小值和最大值?

您可以编写循环遍历数组的函数,将每个值与最小值或最大值进行比较,以找到最小值和最大值。让我们创建这些函数来查找最小值和最大值,

  var marks = [50, 20, 70, 60, 45, 30];
  function findMin(arr) {
    var length = arr.length    var min = Infinity;
    while (length--) {
      if (arr[length] < min) {
        min = arr[len];
      }
    }
    return min;
  }

  function findMax(arr) {
    var length = arr.length    var max = -Infinity;
    while (len--) {
      if (arr[length] > max) {
        max = arr[length];
      }
    }
    return max;
  }

  console.log(findMin(marks));
  console.log(findMax(marks));

247.什么是空语句及其目的?

空语句是一个分号 (;),表示不会执行任何语句,即使 JavaScript 语法需要一个。由于空语句没有动作,您可能认为它的用法很少,但是当您想创建具有空主体的循环时,空语句有时很有用。例如,您可以使用零值初始化一个数组,如下所示,

 // Initialize an array a
 for(int i=0; i < a.length; a[i++] = 0) ;

248.如何获取模块的元数据?

您可以使用import.meta作为元属性的对象,将特定于上下文的元数据暴露给 JavaScript 模块。它包含有关当前模块的信息,例如模块的 URL。在浏览器中,您可能会获得与 NodeJS 不同的元数据。

 <script type="module" src="welcome-module.js"></script>
 console.log(import.meta); // { url: "file:///home/user/welcome-module.js"

249.什么是逗号运算符?

逗号运算符用于从左到右评估其每个操作数并返回最后一个操作数的值。这与数组、对象和函数参数和参数中的逗号用法完全不同。例如,数字表达式的用法如下,

 var x = 1;
 x = (x++, x);

 console.log(x); // 2

250.逗号运算符的优点是什么?

它通常用于在需要单个表达式的位置包含多个表达式。此逗号运算符的常见用法之一是在for循环中提供多个参数。例如,下面的 for 循环使用逗号运算符在单个位置使用多个表达式,

 for (var a = 0, b =10; a <= 10; a++, b--)

您还可以在 return 语句中使用逗号运算符,它在返回之前处理。

 function myFunction() {
    var a = 1;
    return (a += 10, a); // 11
 }

251.什么是 typescript ?

TypeScript 是由 Microsoft 创建的 JavaScript 类型化超集,它添加了可选类型、类、async/await 和许多其他功能,并编译为纯 JavaScript。Angular 完全用 TypeScript 构建并用作主要语言。您可以将其全局安装为

  npm install -g typescript

让我们看一个简单的 TypeScript 用法示例,

  function greeting(name: string): string {
     return "Hello, " + name;
  }

  let user = "Sudheer";

  console.log(greeting(user));

问候方法只允许字符串类型作为参数。


252.javascript 和 typescript 有什么区别?

以下是 javascript 和 typescript 之间的差异列表

功能typescriptjavascript
语言范式面向对象的编程语言脚本语言
打字支持支持静态类型它具有动态类型
模块支持不支持
界面它有接口概念不支持接口
可选参数函数支持可选参数不支持函数的可选参数

253.typescript 相对于 javascript 的优势是什么?

以下是打字稿相对于 javascript 的一些优势,

1.TypeScript 只能在开发时发现编译时错误,并确保减少运行时错误。而 javascript 是一种解释性语言。
2.TypeScript 是强类型或支持静态类型,允许在编译时检查类型正确性。这在 javascript 中不可用。
3.TypeScript 编译器可以将 .ts 文件编译成 ES3、ES4 和 ES5,这与某些浏览器可能不支持的 JavaScript 的 ES6 特性不同。


254.什么是对象初始值设定项?

对象初始值设定项是描述对象初始化的表达式。此表达式的语法表示为以逗号分隔的零或多对属性名称和对象关联值的列表,用花括号 ({}) 括起来。这也称为字面表示法。它是创建对象的方法之一。

 var initObject = {a: 'Haiyong', b: 50, c: {}};

 console.log(initObject.a); // Haiyong

255.什么是构造方法?

构造函数方法是用于创建和初始化在类中创建的对象的特殊方法。如果未指定构造函数方法,则使用默认构造函数。构造函数的示例用法如下,

 class Employee {
   constructor() {
     this.name = "Haiyong";
   }
 }

 var employeeObject = new Employee();

 console.log(employeeObject.name); // Haiyong

256.如果在一个类中多次编写构造函数会发生什么?

类中的“构造函数”是一种特殊的方法,在一个类中只能定义一次。即,如果您在一个类中多次编写构造函数方法,它将抛出SyntaxError错误。

  class Employee {
    constructor() {
      this.name = "Haiyong";
    }
    constructor() {   //  Uncaught SyntaxError: A class may only have one constructor(未捕获的语法错误:一个类可能只有一个构造函数)
      this.age = 30;
    }
  }

  var employeeObject = new Employee();

  console.log(employeeObject.name);

257.如何调用父类的构造函数?

您可以使用super关键字来调用父类的构造函数。请记住,super()必须在使用“this”引用之前调用。否则会导致引用错误。让我们使用它,

class Square extends Rectangle {
   constructor(length) {
     super(length, length);
     this.name = 'Square';
   }

   get area() {
     return this.width * this.height;
   }

   set area(value) {
     this.area = value;
   }
 }

258.你如何获得一个对象的 prototype?

您可以使用该Object.getPrototypeOf(obj)方法返回指定对象的原型。即内部prototype属性的值。如果没有继承的属性,则null返回值。

 const newPrototype = {};
 const newObject = Object.create(newPrototype);

 console.log(Object.getPrototypeOf(newObject) === newPrototype); // true

259.如果我为 getPrototype 方法传递字符串类型会发生什么?

在 ES5 中,如果 obj 参数不是对象,它将抛出 TypeError 异常。而在 ES2015 中,该参数将被强制转换为Object.

 // ES5
 Object.getPrototypeOf('CSDN'); // TypeError: "CSDN" is not an object
 // ES2015
 Object.getPrototypeOf('CSDN'); // String.prototype

260.如何将一个对象的 prototype 设置为另一个对象?

您可以使用将指定对象Object.setPrototypeOf()的原型(即内部Prototype属性)设置为另一个对象或null 的方法。例如,如果要将方形对象的原型设置为矩形对象,则如下所示,

 Object.setPrototypeOf(Square.prototype, Rectangle.prototype);
 Object.setPrototypeOf({}, null);

261.你如何检查一个对象是否可以扩展?

该Object.isExtensible()方法用于确定对象是否可扩展。即,它是否可以添加新属性。

 const newObject = {};
 console.log(Object.isExtensible(newObject)); //true

注意:默认情况下,所有对象都是可扩展的。即,可以添加或修改新属性。


262.如何防止对象扩展?

该Object.preventExtensions()方法用于防止向对象添加新属性。换句话说,它可以防止将来对对象进行扩展。让我们看看这个属性的用法,

 const newObject = {};
 Object.preventExtensions(newObject); // 不可扩展

 try {
   Object.defineProperty(newObject, 'newProperty', { // 添加新属性
     value: 100
   });
 } catch (e) {
   console.log(e); // 类型错误:无法定义属性 newProperty,对象不可扩展
 }

263.使对象不可扩展的不同方法有哪些?

您可以通过 3 种方式将对象标记为不可扩展,

1.Object.preventExtensions
2.Object.seal
3.Object.freeze

 var newObject = {};

 Object.preventExtensions(newObject); // 防止对象不可扩展
 Object.isExtensible(newObject); // false

 var sealedObject = Object.seal({}); // 密封对象不可扩展
 Object.isExtensible(sealedObject); // false

 var frozenObject = Object.freeze({}); // 冻结的对象是不可扩展的
 Object.isExtensible(frozenObject); // false

264.如何在一个对象上定义多个属性?

该Object.defineProperties()方法用于直接在对象上定义新属性或修改现有属性并返回该对象。让我们在一个空对象上定义多个属性,

 const newObject = {};

 Object.defineProperties(newObject, {
   newProperty1: {
     value: 'Haiyong',
     writable: true
   },
   newProperty2: {}
 });

265.JavaScript 中的 MEAN 是什么?

MEAN(MongoDB、Express、AngularJS 和 Node.js)堆栈是最流行的开源 JavaScript 软件技术堆栈,可用于构建动态 Web 应用程序,您可以在其中编写 Web 项目的服务器端和客户端两部分完全在 JavaScript 中。


266.什么是 javascript 中的混淆?

混淆是故意创建人类难以理解的混淆 javascript 代码(即源代码或机器代码)的行为。它类似于加密,但机器可以理解代码并执行它。
让我们在混淆之前看看下面的函数,

 function greeting() {
    console.log('Hello, welcome to JS world');
 }

在代码混淆之后,它会出现如下,

 eval(function(p,a,c,k,e,d){e=function(c){return c};if(!''.replace(/^/,String)

267.为什么需要混淆?

以下是混淆的几个原因,

1.代码大小将减少。所以服务器和客户端之间的数据传输会很快。
2.它对外界隐藏业务逻辑并保护代码不受他人影响
3.逆向工程难度很大
4.下载时间将减少


268.什么是Minification(缩小)?

缩小是删除所有不必要的字符(删除空格)的过程,变量将被重命名而不改变其功能。这也是一种混淆。


269.缩小有什么好处?

通常情况下,建议在流量大和资源密集需求的情况下使用最小化。它减少了文件大小,具有以下好处,

1.减少网页的加载时间
2.节省带宽使用量


270.混淆和加密有什么区别?

以下是混淆和加密之间的主要区别,

特色混淆加密
定义以任何其他形式更改任何数据的形式使用密钥将信息的形式更改为不可读的格式
解码的钥匙无需任何密钥即可解码它是必需的
目标数据格式它将被转换为复杂的形式转换成不可读的格式

271.常用的缩小工具有哪些?

有许多在线/离线工具可以缩小 javascript 文件,

  • 谷歌的 Closure 编译器

  • jsmin

  • javascript-minifier.com

  • Prettydiff.com


272.你如何使用 javascript 执行表单验证?

JavaScript 可用于执行 HTML 表单验证。比如表单域为空,函数需要通知,返回false,防止表单被提交。
让我们以 html 形式执行用户登录,

 <form name="myForm" onsubmit="return validateForm()" method="post">
 User name: <input type="text" name="uname">
 <input type="submit" value="Submit">
 </form>

用户登录验证如下,

 function validateForm() {
   var x = document.forms["myForm"]["uname"].value;
   if (x == "") {
     alert("The username shouldn't be empty");
     return false;
   }
 }

273.如何在没有 javascript 的情况下执行表单验证?

您可以在不使用 javascript 的情况下自动执行 HTML 表单验证。通过应用required属性启用验证以防止在输入为空时提交表单。

 <form method="post">
   <input type="text" name="uname" required>
   <input type="submit" value="Submit">
 </form>

注意:自动表单验证在 Internet Explorer 9 或更早版本中不起作用。


274.可用于约束验证的 DOM 方法有哪些?

以下 DOM 方法可用于对无效输入进行约束验证,

1.checkValidity():如果输入元素包含有效数据,则返回 true。
2.setCustomValidity():用于设置输入元素的validationMessage 属性。让我们使用带有 DOM 验证的用户登录表单

 function myFunction() {
   var userName = document.getElementById("uname");
   if (!userName.checkValidity()) {
     document.getElementById("message").innerHTML = userName.validationMessage;
   } else {
     document.getElementById("message").innerHTML = "Entered a valid username";
   }
 }

275.什么是可用的约束验证 DOM 属性?

下面是一些可用的约束验证 DOM 属性的列表,

1.validity:它提供与输入元素有效性相关的布尔属性列表。
2.validationMessage:当有效性为假时显示消息。
3.willValidate:指示输入元素是否将被验证。


276.什么是有效性属性列表?

输入元素的有效性属性提供一组与数据有效性相关的属性。

1.customError:如果设置了自定义有效性消息,则返回 true。
2.patternMismatch:如果元素的值与其模式属性不匹配,则返回 true。
3.rangeOverflow:如果元素的值大于其 max 属性,则返回 true。
4.rangeUnderflow:如果元素的值小于其 min 属性,则返回 true。
5.stepMismatch:如果元素的值根据 step 属性无效,则返回 true。
6.tooLong:如果元素的值超过其 maxLength 属性,则返回 true。
7.typeMismatch:如果元素的值根据 type 属性无效,则返回 true。
8.valueMissing:如果具有必需属性的元素没有值,则返回 true。
9.valid:如果元素的值有效,则返回 true。


277.举例使用 rangeOverflow 属性?

如果元素的值大于其 max 属性,则 rangeOverflow 属性返回 true。例如,如果值大于 100,下面的表单提交会引发错误,

 <input id="age" type="number" max="100">
 <button onclick="myOverflowFunction()">OK</button>
 function myOverflowFunction() {
   if (document.getElementById("age").validity.rangeOverflow) {
     alert("The mentioned age is not allowed");
   }
 }

278.javascript 中是否提供枚举功能?

不,javascript 本身不支持枚举。但是有不同种类的解决方案可以模拟它们,即使它们可能无法提供精确的等效项。例如,您可以在对象上使用冻结或密封,

 var DaysEnum = Object.freeze({"monday":1, "tuesday":2, "wednesday":3, ...})

279.什么是枚举?

枚举是一种将变量限制为一组预定义常量中的一个值的类型。JavaScript 没有枚举,但 typescript 提供了内置的枚举支持。

 enum Color {
  RED, GREEN, BLUE
 }

280.你如何列出一个对象的所有属性?

您可以使用该Object.getOwnPropertyNames()方法返回直接在给定对象中找到的所有属性的数组。让我们在一个例子中使用它,

 const newObject = {
   a: 1,
   b: 2,
   c: 3
 };

 console.log(Object.getOwnPropertyNames(newObject));  ["a", "b", "c"]

281.如何获取对象的属性描述符?

您可以使用Object.getOwnPropertyDescriptors()返回给定对象的所有自己的属性描述符的方法。此方法的示例用法如下,

  const newObject = {
    a: 1,
    b: 2,
    c: 3
  };
 const descriptorsObject = Object.getOwnPropertyDescriptors(newObject);
 console.log(descriptorsObject.a.writable); //true
 console.log(descriptorsObject.a.configurable); //true
 console.log(descriptorsObject.a.enumerable); //true
 console.log(descriptorsObject.a.value); // 1

282.属性描述符提供的属性是什么?

属性描述符是具有以下属性的记录

1.value:与属性关联的值
2.writable:确定与属性关联的值是否可以更改
3.configurable:如果可以更改此属性描述符的类型并且可以从相应的对象中删除该属性,则返回 true。
4.enumerable:确定在枚举对应对象上的属性时是否出现该属性。
5.set: 一个作为属性设置器的函数
6.get:作为属性的 getter 的函数


283.你如何扩展类?

extends关键字在类声明/表达式中用于创建一个类,该类是另一个类的子类。它可用于子类化自定义类以及内置对象。语法如下,

 class ChildClass extends ParentClass { ... }

让我们以 Polygon 父类的 Square 子类为例,

  class Square extends Rectangle {
    constructor(length) {
      super(length, length);
      this.name = 'Square';
    }

    get area() {
      return this.width * this.height;
    }

    set area(value) {
      this.area = value;
    }
  }

284.如何在不重新加载页面的情况下修改 url?

window.location.url属性将有助于修改 url,但它会重新加载页面。HTML5 引入了 history.pushState()history.replaceState() 方法,分别允许您添加和修改历史条目。例如,您可以使用 pushState 如下,

 window.history.pushState('page2', 'Title', '/page2.html');

285.如何检查数组是否包含特定值?

Array#includes()方法用于通过返回 true 或 false 来确定数组是否在其条目中包含特定值。让我们看一个在数组中查找元素(数字和字符串)的示例。

 var numericArray = [1, 2, 3, 4];
 console.log(numericArray.includes(3)); // true

 var stringArray = ['green', 'yellow', 'blue'];
 console.log(stringArray.includes('blue')); //true

286.你如何比较标量数组?

您可以使用 length 和数组的 every 方法来比较两个标量(直接使用 === 进行比较)数组。这些表达式的组合可以给出预期的结果,

 const arrayFirst = [1,2,3,4,5];
 const arraySecond = [1,2,3,4,5];
 console.log(arrayFirst.length === arraySecond.length && arrayFirst.every((value, index) => value === arraySecond[index])); // true

如果你想比较数组而不考虑顺序,那么你应该先对它们进行排序,

const arrayFirst = [2,3,1,4,5];const arraySecond = [1,2,3,4,5];console.log(arrayFirst.length === arraySecond.length && arrayFirst.sort().every((value, index) => value === arraySecond[index])); //true

287.如何从获取参数中获取值?

该new URL()对象接受 url 字符串searchParams,该对象的属性可用于访问获取参数。请记住,您可能需要使用 polyfill 或window.location在旧浏览器(包括 IE)中访问 URL。

let urlString = "http://www./about.html?x=1&y=2&z=3"; //window.location.hreflet url = new URL(urlString);let parameterZ = url.searchParams.get("z");console.log(parameterZ); // 3



288.你如何用逗号作为千位分隔符打印数字?

您可以使用Number.prototype.toLocaleString()返回带有语言敏感表示的字符串的方法,例如千位分隔符、货币等。

function convertToThousandFormat(x){return x.toLocaleString(); // 12,345.679}console.log(convertToThousandFormat(12345.6789));



289.java和javascript有什么区别?

两者都是完全不相关的编程语言,它们之间没有任何关系。Java 是静态类型的、编译的、在自己的 VM 上运行。而 Javascript 是在浏览器和 nodejs 环境中动态输入、解释和运行的。让我们看看表格格式的主要区别

特色javaJavaScript
类型它是一种强类型语言它是一种动态类型语言
范式面向对象编程基于原型的编程
范围块作用域函数作用域
并发基于线程基于事件
内存使用更多内存使用更少的内存。因此它将用于网页

具体区别参考:https://haiyong.blog.csdn.net/article/details/117409345



290.javascript是否支持命名空间?

JavaScript 默认不支持命名空间。因此,如果您创建任何元素(函数、方法、对象、变量),那么它就会变成全局并污染全局命名空间。让我们举个例子,定义两个没有任何命名空间的函数

function func1() {console.log("这是第一个定义");}function func1() {console.log("这是第二个定义");}func1(); // 这是第二个定义

它总是调用第二个函数定义。在这种情况下,namespace 将解决名称冲突问题。



291.你如何声明命名空间?

尽管 JavaScript 缺少命名空间,但我们可以使用 Objects 、 IIFE 来创建命名空间。

使用对象字面量表示法:让我们将变量和函数包装在充当命名空间的对象字面量中。之后,您可以使用对象表示法访问它们

var namespaceOne = {function func1() {console.log("This is a first definition");}}var namespaceTwo = {function func1() {console.log("This is a second definition");}}namespaceOne.func1(); // This is a first definitionnamespaceTwo.func1(); // This is a second definition

使用 IIFE(立即调用函数表达式): IIFE 的外一对括号为其内部的所有代码创建了一个局部作用域,并使匿名函数成为一个函数表达式。因此,您可以在两个不同的函数表达式中创建相同的函数来充当命名空间。

(function() {function fun1(){console.log("这是第一个定义");} fun1();}());(function() {function fun1(){console.log("这是第二个定义");} fun1();}());

使用块和 let/const 声明:在 ECMAScript 6 中,您可以简单地使用块和 let 声明来将变量的范围限制为块。

{let myFunction= function fun1(){console.log("这是第一个定义");}myFunction();}//myFunction(): ReferenceError: myFunction 未定义。{let myFunction= function fun1(){console.log("这是第二个定义");}myFunction();}//myFunction(): ReferenceError: myFunction 未定义。



292.如何从父页面调用 iframe 中的 javascript 代码?

最初需要使用document.getElementBy或访问 iFrame window.frames。在contentWindowiFrame 的该属性提供对 targetFunction 的访问权限之后

document.getElementById('targetFrame').contentWindow.targetFunction();window.frames[0].frameElement.contentWindow.targetFunction(); // 以这种方式访问 iframe 可能不适用于最新版本的 chrome 和 firefox



293.如何从日期获取时区偏移量?

您可以使用getTimezoneOffset日期对象的方法。此方法返回从当前语言环境(主机系统设置)到 UTC 的时区差异(以分钟为单位)

var offset = new Date().getTimezoneOffset();console.log(offset); // -480



294.如何动态加载 CSS 和 JS 文件?

您可以在 DOM 中创建 link 和 script 元素,并将它们作为 child 附加到 head 标记。让我们创建一个函数来添加脚本和样式资源,如下所示,

function loadAssets(filename, filetype) {if (filetype == "css") { // External CSS filevar fileReference = document.createElement("link")fileReference.setAttribute("rel", "stylesheet");fileReference.setAttribute("type", "text/css");fileReference.setAttribute("href", filename);} else if (filetype == "js") { // External JavaScript filevar fileReference = document.createElement('script');fileReference.setAttribute("type", "text/javascript");fileReference.setAttribute("src", filename);}if (typeof fileReference != "undefined")document.getElementsByTagName("head")[0].appendChild(fileReference)}



295.在 DOM 中查找 HTML 元素的不同方法有哪些?

如果要访问 HTML 页面中的任何元素,则需要从访问文档对象开始。稍后您可以使用以下任何一种方法来查找 HTML 元素,

1.document.getElementById(id):通过Id查找元素
2.document.getElementsByTagName(name):通过标签名查找元素
3.document.getElementsByClassName(name):通过类名查找元素



296.什么是jQuery?

jQuery 是一个流行的跨浏览器 JavaScript 库,它通过最小化浏览器之间的差异来提供文档对象模型 (DOM) 遍历、事件处理、动画和 AJAX 交互。它以其“少写,多做”的理念而广为人知。例如,您可以使用 jQuery 在页面加载时显示欢迎消息,如下所示,

$(document).ready(function(){ // 它选择文档并在页面加载时应用该功能alert('Welcome to jQuery world');});

注意:您可以从 jquery 的官方网站下载它,也可以从 CDN(如 google)安装它。



297.什么是 V8 JavaScript 引擎?

V8 是 Google Chrome 浏览器使用的开源高性能 JavaScript 引擎,用 C++ 编写。它也在 node.js 项目中使用。它实现了 ECMAScript 和 WebAssembly,并在 Windows 7 或更高版本、macOS 10.12+ 和使用 x64、IA-32、ARM 或 MIPS 处理器的 Linux 系统上运行。

注意:它可以独立运行,也可以嵌入到任何 C++ 应用程序中。



298.为什么我们称javascript为动态语言?

JavaScript 是一种松散类型或动态语言,因为 JavaScript 中的变量不直接与任何特定的值类型相关联,任何变量都可以分配/重新分配所有类型的值。

let age = 50; // age is a number nowage = 'old'; // age is a string nowage = true; // age is a boolean



299.什么是空运算符?

void运算符计算给定表达式,然后返回未定义的(即,不返回值)。语法如下,

void ()void 

让我们在没有任何重定向或重新加载的情况下显示一条消息

<a href="javascript:void(alert('Welcome to JS world'))">Click here to see a message</a>

注意:此运算符通常用于获取未定义的原始值,使用“void(0)”。



300.如何设置光标等待?

可以使用属性“cursor”将游标设置为在 JavaScript 中等待。让我们使用以下函数在页面加载时执行此行为。

function myFunction() {window.document.body.style.cursor = "wait";}

并且在页面加载时调用此函数

<body onload="myFunction()">



301.你如何创建一个无限循环?

您可以使用 for 和 while 循环创建无限循环,而无需使用任何表达式。就 ESLint 和代码优化器工具而言,for 循环构造或语法是更好的方法,

for (;;) {}while(true) {}



302.为什么需要避免 with 语句?

JavaScript 的 with 语句旨在为编写对对象的重复访问提供速记。因此,它可以通过减少重复冗长的对象引用的需要来帮助减小文件大小,而不会降低性能。让我们举一个例子,它用于在多次访问一个对象时避免冗余。

a.b.c.greeting = 'welcome';a.b.c.age = 32;

使用with它变成:

with(a.b.c) {greeting = "welcome";age = 32;}

但是这个with语句会产生性能问题,因为人们无法预测一个参数是指向一个实变量还是指向 with 参数中的一个属性。



303.以下 for 循环的输出是什么?

for (var i = 0; i < 4; i++) { // 全局范围setTimeout(() => console.log(i));}for (let i = 0; i < 4; i++) { // 块作用域setTimeout(() => console.log(i));}

上述 for 循环的输出是 4 4 4 4 和 0 1 2 3

说明:由于javascript的事件队列/循环,setTimeout循环执行完毕后会调用回调函数。由于变量 i 是用var关键字声明的,它变成了一个全局变量,并且在setTimeout调用time函数时使用迭代的值等于 4 。因此,第一个循环的输出是4 4 4 4。

而在第二个循环中,变量 i 被声明为let关键字,它变成了一个块范围的变量,并且每次迭代都保存一个新值 (0, 1 ,2 3)。因此,第一个循环的输出是0 1 2 3。



304.列出 ES6 的一些特性?

下面是 ES6 的一些新特性的列表,

1.支持常量或不可变变量
2.对变量、常量和函数的块范围支持
3.箭头函数
4.默认参数
5.Rest and Spread 参数
6.Template Literals(模板字符串)
7.多行字符串
8.解构赋值
9.增强的对象文字
10.Promises
11.Classes
12.Modules



305.什么是 ES6?

ES6 是 javascript 语言的第六版,它于 2015 年 6 月发布。它最初被称为 ECMAScript 6 (ES6),后来更名为 ECMAScript 2015。几乎所有现代浏览器都支持 ES6,但对于旧浏览器有很多转译器,比如 Babel.js 等。



306.我可以重新声明 let 和 const 变量吗?

不,您不能重新声明 let 和 const 变量。如果你这样做,它会抛出以下错误

Uncaught SyntaxError: Identifier 'someVariable' has already been declared

说明:带有var关键字的变量声明引用了一个函数作用域,由于提升特性,该变量被视为在封闭作用域的顶部声明。因此,对同一个提升变量做出贡献的所有多个声明都没有任何错误。让我们举个例子,为 var 和 let/const 变量在同一范围内重新声明变量。

var name = 'Haiyong';function myFunc() {var name = 'Nick';var name = 'Abraham'; // 在同一功能块中重新分配alert(name); // Abraham}myFunc();alert(name); // Haiyong

块范围的多声明抛出语法错误,

let name = 'Haiyong';function myFunc() {let name = 'Nick';let name = 'Abraham'; // 未捕获的语法错误:标识符"name"已被声明alert(name);}myFunc();alert(name);



307.是 const 变量使值不可变吗?

不, const 变量不会使值不可变。但它不允许后续赋值(即,您可以使用赋值声明但不能稍后赋值)

const userList = [];userList.push('CSDN'); // 即使不能重新分配也可以变异console.log(userList); // ['CSDN']



308.什么是默认参数?

在 E5 中,我们需要依赖逻辑 OR 运算符来处理函数参数的默认值。而在 ES6 中,默认函数参数功能允许在未传递值或未定义时使用默认值初始化参数。让我们将行为与示例进行比较,

//ES5var calculateArea = function(height, width) {height = height || 50;width = width || 60;return width * height;}console.log(calculateArea()); //300

默认参数使初始化更简单,

//ES6var calculateArea = function(height = 50, width = 60) {return width * height;}console.log(calculateArea()); //300



309.什么是模板字面量?

模板文字或模板字符串是允许嵌入表达式的字符串文字。它们由反引号 (`) 字符而不是双引号或单引号括起来。
在 E6 中,此功能允许使用如下动态表达式,

var greeting = `Welcome to JS World, Mr. ${firstName} ${lastName}.`

在 ES5 中,你需要像下面这样的中断字符串,

var greeting = 'Welcome to JS World, Mr.' + firstName + ' ' + lastName.

注意:您可以将多行字符串和字符串插值功能与模板文字一起使用。



310.如何在模板文字中编写多行字符串?

在 ES5 中,您必须使用换行符(’\n’)和连接符号(+)来获得多行字符串。

 console.log('This is string sentence 1\n' +
 'This is string sentence 2');

而在 ES6 中,您不需要提及任何换行序列字符,

 console.log(`This is string sentence
 'This is string sentence 2`);



311.什么是嵌套模板?

嵌套模板是模板文字语法中支持的一项功能,它允许在模板内的占位符 ${ } 内使用内部反引号。例如,下面的嵌套模板用于根据用户权限显示图标,而外部模板检查平台类型,

 const iconStyles = `icon ${ isMobilePlatform() ? '' :
  `icon-${user.isAuthorized ? 'submit' : 'disabled'}` }`;

您也可以在不嵌套模板功能的情况下编写上述用例。但是,嵌套模板功能更加紧凑和可读。

 //无嵌套模板
  const iconStyles = `icon ${ isMobilePlatform() ? '' :
   (user.isAuthorized ? 'icon-submit' : 'icon-disabled'}`;



312.什么是标记模板?

标记模板是模板的高级形式,其中标记允许您使用函数解析模板文字。tag 函数接受第一个参数作为字符串数组,其余参数作为表达式。此函数还可以根据参数返回操作过的字符串。让我们看看组织中 IT 专业技能集的这种标记模板行为的使用情况,

 var user1 = 'Haiyong';
 var skill1 = 'JavaScript';
 var experience1 = 15;

 var user2 = 'CSDN';
 var skill2 = 'JavaScript';
 var experience2 = 5;

 function myInfoTag(strings, userExp, experienceExp, skillExp) {
   var str0 = strings[0]; // "Mr/Ms. "
   var str1 = strings[1]; // " is a/an "
   var str2 = strings[2]; // "in"

   var expertiseStr;
   if (experienceExp > 10){
     expertiseStr = 'expert developer';
   } else if(skillExp > 5 && skillExp <= 10) {
     expertiseStr = 'senior developer';
   } else {
     expertiseStr = 'junior developer';
   }

   return ${str0}${userExp}${str1}${expertiseStr}${str2}${skillExp};
 }

 var output1 = myInfoTag`Mr/Ms. ${ user1 } is a/an ${ experience1 } in ${skill1}`;
 var output2 = myInfoTag`Mr/Ms. ${ user2 } is a/an ${ experience2 } in ${skill2}`;

 console.log(output1);// Mr/Ms. Haiyong is a/an expert developer in JavaScript(是一位 JavaScript 专家开发人员)
 console.log(output2);// Mr/Ms. CSDN is a/an junior developer in JavaScript(是一名初级 JavaScript 开发人员)



313.什么是原始字符串?

ES6 提供了一个原始字符串特性,使用该String.raw()方法来获取模板字符串的原始字符串形式。此功能允许您在输入原始字符串时访问它们,而无需处理转义序列。例如,用法如下,

  var calculationString = String.raw `The sum of numbers is \n${1+2+3+4}!`;
  console.log(calculationString); // The sum of numbers is 10

如果不使用原始字符串,将通过多行显示输出来处理换行符序列

  var calculationString = `The sum of numbers is \n${1+2+3+4}!`;
  console.log(calculationString);
  // The sum of numbers is
  // 10

此外,原始属性可用于标记函数的第一个参数

  function tag(strings) {
     console.log(strings.raw[0]);
  }



314.什么是解构赋值?

解构赋值是一个 JavaScript 表达式,它可以将数组中的值或对象中的属性解包为不同的变量。
让我们使用解构赋值从数组中获取月份值

 var [one, two, three] = ['JAN', 'FEB', 'MARCH'];

 console.log(one); // "JAN"
 console.log(two); // "FEB"
 console.log(three); // "MARCH"

并且您可以使用解构赋值获取对象的用户属性,

 var {name, age} = {name: 'Haiyong', age: 22};

 console.log(name); // Haiyong
 console.log(age); // 22



315.解构赋值中的默认值是什么?

如果在解构赋值期间从数组或对象中解压缩出来的值未定义,则可以为变量分配一个默认值。它有助于避免为每个分配单独设置默认值。让我们以数组和对象用例为例,

数组解构:

var x, y, z;[x=2, y=4, z=6] = [10];console.log(x); // 10console.log(y); // 4console.log(z); // 6

对象解构:

var {x=2, y=4, z=6} = {x: 10};console.log(x); // 10console.log(y); // 4console.log(z); // 6



316.你如何在解构赋值中交换变量?

如果不使用解构赋值,交换两个值需要一个临时变量。而使用解构功能,可以在一个解构表达式中交换两个变量值。让我们在数组解构赋值中交换两个数字变量,

var x = 10, y = 20;[x, y] = [y, x];console.log(x); // 20console.log(y); // 10



317.什么是增强的对象字面量?

对象字面量可以很容易地快速创建带有花括号内的属性的对象。例如,它为公共对象属性定义提供了更短的语法,如下所示。

//ES6var x = 10, y = 20obj = { x, y }console.log(obj); // {x: 10, y:20}//ES5var x = 10, y = 20obj = { x : x, y : y}console.log(obj); // {x: 10, y:20}

318.什么是动态导入?

使用import()函数语法的动态导入允许我们通过使用 Promise 或 async/await 语法按需加载模块。目前此功能在stage4 提案中。动态导入的主要优点是减少了我们的 bundle 的大小、我们请求的大小/有效负载响应以及用户体验的整体改进。

动态导入的语法如下,

import('./Module').then(Module => Module.method());



319.动态导入的用例是什么?

以下是使用动态导入而不是静态导入的一些用例,

按需或有条件地导入模块。例如,如果您想在旧版浏览器上加载 polyfill

 if (isLegacyBrowser()) {
     import(···)
     .then(···);
 }

在运行时计算模块说明符。例如,您可以将其用于国际化。

 import(`messages_${getLocale()}.js`).then(···);

从常规脚本中导入模块而不是模块。



320.什么是typed arrays (类型数组)?

类型化数组是来自 ECMAScript 6 API 的类数组对象,用于处理二进制数据。JavaScript 提供了 8 种 Typed 数组类型,

1.Int8Array:一个 8 位有符号整数数组
2.Int16Array:16 位有符号整数数组
3.Int32Array:一个 32 位有符号整数数组
4.Uint8Array:8 位无符号整数数组
5.Uint16Array:16 位无符号整数数组
6.Uint32Array:一个 32 位无符号整数数组
7.Float32Array:32 位浮点数数组
8.Float64Array:64 位浮点数数组

例如,您可以创建一个 8 位有符号整数数组,如下所示

 const a = new Int8Array();
 // 您可以预先分配 n 个字节
 const bytes = 1024
 const a = new Int8Array(bytes)



321.模块加载器的优点是什么?

模块加载器提供以下功能,

1.动态加载
2.状态隔离
3.全局命名空间隔离
4.编译钩子
5.嵌套虚拟化



322.什么是 collation?

排序规则用于对一组字符串进行排序并在一组字符串中进行搜索。它由区域设置参数化并了解 Unicode。让我们来看看比较和排序功能,

比较:

 var list = [ "ä", "a", "z" ]; // 在德语中,“ä”与“a”一起排序,而在瑞典语中,“ä”在“z”之后排序
 var l10nDE = new Intl.Collator("de");
 var l10nSV = new Intl.Collator("sv");
 console.log(l10nDE.compare("ä", "z") === -1); // true
 console.log(l10nSV.compare("ä", "z") === +1); // true

排序:

 var list = [ "ä", "a", "z" ]; // 在德语中,“ä”与“a”一起排序,而在瑞典语中,“ä”在“z”之后排序
 var l10nDE = new Intl.Collator("de");
 var l10nSV = new Intl.Collator("sv");
 console.log(list.sort(l10nDE.compare)) // [ "a", "ä", "z" ]
 console.log(list.sort(l10nSV.compare)) // [ "a", "z", "ä" ]



323.什么是…of 语句?

for…of 语句创建一个循环迭代可迭代对象或元素,例如内置字符串、数组、类数组对象(如参数或 NodeList)、TypedArray、Map、Set 和用户定义的可迭代对象。数组上 for…of 语句的基本用法如下,

 let arrayIterable = [10, 20, 30, 40, 50];

 for (let value of arrayIterable) {
   value ++;
   console.log(value); // 11 21 31 41 51
 }



324.下面展开运算符数组的输出是什么?

 [...'John Resig']

数组的输出为 ['J’, 'o’, 'h’, 'n’, '’, 'R’, 'e’, 's’, 'i’, 'g’]

说明:字符串是一种可迭代类型,数组中的扩展运算符将可迭代的每个字符映射到一个元素。因此,字符串的每个字符都成为数组中的一个元素。



325.PostMessage 安全吗?

是的,只要程序员/开发人员仔细检查到达消息的来源和来源,就可以认为 postMessages 非常安全。但是,如果您尝试在不验证消息来源的情况下发送/接收消息,则会产生跨站点脚本攻击。



326.postmessage目标源作为通配符有什么问题?

postMessage 方法的第二个参数指定允许哪个源接收消息。如果您使用通配符“*”作为参数,则允许任何来源接收消息。在这种情况下,发送方窗口在发送消息时无法知道目标窗口是否在目标源。如果目标窗口已导航到另一个原点,则另一个原点将接收数据。因此,这可能会导致 XSS 漏洞。

 targetWindow.postMessage(message, '*');



327.你如何避免收到来自攻击者的 postMessages?

您如何避免收到来自攻击者的 postMessages
由于侦听器侦听任何消息,攻击者可以通过从攻击者的来源发送消息来欺骗应用程序,这给人的印象是接收者从实际发送者的窗口收到了消息。您可以通过使用“message.origin”属性在接收者端验证消息的来源来避免此问题。例如,让我们在接收方www.上检查发送方的来源http://www.

 //监听器打开 http://www./
 window.addEventListener("message", function(message){
     if(/^http://www\.some-sender\.com$/.test(message.origin)){
          console.log('You received the data from valid sender', message.data);
    }
 });



328.我可以完全避免使用 postMessages 吗?

您无法完全(或 100%)避免使用 postMessages。尽管考虑到风险,您的应用程序不使用 postMessage,但许多第三方脚本使用 postMessage 与第三方服务进行通信。因此,您的应用程序可能在您不知情的情况下使用 postMessage。



329.postMessages 是否同步?

postMessages 在 IE8 浏览器中是同步的,但它们在 IE9 和所有其他现代浏览器(即 IE9+、Firefox、Chrome、Safari)中是异步的。由于这种异步行为,我们在 postMessage 返回时使用回调机制。



330.Javascript 是什么范式?

JavaScript 是一种多范式语言,支持命令式/过程式编程、面向对象编程和函数式编程。JavaScript 支持具有原型继承的面向对象编程。



331.内部和外部 javascript有什么区别?

内部 JavaScript:它是脚本标签内的源代码。
外部 JavaScript:源代码存储在外部文件中(以 .js 扩展名存储)并在标签中引用。



332.JavaScript 是否比服务器端脚本更快?

是的,JavaScript 比服务器端脚本更快。因为 JavaScript 是一个客户端脚本,它不需要任何网络服务器的帮助来进行计算或计算。因此 JavaScript 总是比任何服务器端脚本(如 ASP、PHP 等)都快。



333.你如何获得复选框的状态?

您可以checked在 DOM 中选定的复选框上应用该属性。如果值为 ,则True表示复选框已选中,否则未选中。例如,下面的 HTML 复选框元素可以使用 javascript 访问,如下所示,

   <input type="checkbox" name="checkboxname" value="Agree"> 同意条件<br>
 console.log(document.getElementById('checkboxname’).checked); // true or false



334.双波浪号运算符的目的是什么?

双波浪号运算符 (~~) 称为双非按位运算符。这个运算符将成为 Math.floor() 的更快替代品。



335.你如何将字符转换为 ASCII 码?

您可以使用该String.prototype.charCodeAt()方法将字符串字符转换为 ASCII 数字。例如,让我们找到 'ABC’ 字符串的第一个字母的 ASCII 代码,

 "ABC".charCodeAt(0) // returns 65

而String.fromCharCode()方法将数字转换为相等的 ASCII 字符。

 String.fromCharCode(65,66,67); // returns 'ABC'



336.什么是数组缓冲区?

ArrayBuffer 对象用于表示通用的、固定长度的原始二进制数据缓冲区。您可以按如下方式创建它,

 let buffer = new ArrayBuffer(16); // 创建一个长度为 16 的缓冲区
 alert(buffer.byteLength); // 16

要操作 ArrayBuffer,我们需要使用“视图”对象。

 //创建一个引用缓冲区的 DataView
  let view = new DataView(buffer);



337.下面的字符串表达式的输出是什么?

 console.log("Welcome to JS world"[0])

上述表达式的输出是“W”。

说明:字符串上带有特定索引的括号表示法返回特定位置的字符。因此,它返回字符串的字符“W”。由于 IE7 及以下版本不支持此功能,因此您可能需要使用 .charAt() 方法来获得所需的结果。



338.Error对象的目的是什么?

Error 构造函数创建一个错误对象,并在发生运行时错误时抛出错误对象的实例。Error 对象还可以用作用户定义异常的基础对象。错误对象的语法如下,

 new Error([message[, fileName[, lineNumber]]])

您可以在 try…catch 块中使用 Error 对象抛出用户定义的异常或错误,如下所示,

 try {
   if(withdraw > balance)
   throw new Error("Oops! You don't have enough balance");
 } catch (e) {
   console.log(e.name + ': ' + e.message);
 }



339.EvalError 对象的目的是什么?

EvalError 对象指示有关全局eval()函数的错误。尽管 JavaScript 不再抛出此异常,但 EvalError 对象仍保持兼容性。这个表达式的语法如下,

 new EvalError([message[, fileName[, lineNumber]]])

你可以在 try…catch 块中抛出 EvalError ,如下所示,

 try {
   throw new EvalError('Eval function error', 'someFile.js', 100);
 } catch (e) {
   console.log(e.message, e.name, e.fileName);              // "Eval function error", "EvalError", "someFile.js"



340.从非严格模式到严格模式抛出的案例错误列表是什么?

当您应用“使用严格”时;语法,下面的一些情况会在执行脚本之前抛出 SyntaxError

使用八进制语法时

 var n = 022;

1.使用with语句
2.在变量名上使用 delete 运算符时
3.使用 eval 或 arguments 作为变量或函数参数名称
4.当您使用新保留的关键字时
5.当你在块中声明一个函数时

 if (someCondition) { function f() {} }

因此,上述案例中的错误有助于避免开发/生产环境中的错误。



341.是否所有对象都有prototypes(原型)?

不是。除了由用户创建的基础对象或使用 new 关键字创建的对象之外,所有对象都有原型。



342.parameter(形参)和argument(实参)有什么区别?

参数是函数定义的变量名,而参数表示函数被调用时赋予的值。让我们用一个简单的函数来解释这一点

 function myFunction(parameter1, parameter2, parameter3) {
   console.log(arguments[0]) // "argument1"
   console.log(arguments[1]) // "argument2"
   console.log(arguments[2]) // "argument3"
 }
 myFunction("argument1", "argument2", "argument3")



343.数组中 some 方法的目的是什么?

some() 方法用于测试数组中是否至少有一个元素通过了提供的函数实现的测试。该方法返回一个布尔值。让我们举一个例子来测试任何奇数元素,

 var array = [1, 2, 3, 4, 5, 6 ,7, 8, 9, 10];
 var odd = element ==> element % 2 !== 0;
 console.log(array.some(odd)); // true(奇数元素存在)



344.你如何组合两个或多个数组?

concat() 方法用于通过返回包含所有元素的新数组来连接两个或多个数组。语法如下,

array1.concat(array2, array3, ..., arrayX)

让我们以数组与蔬菜和水果数组的串联为例,

  var veggies = ["Tomato", "Carrot", "Cabbage"];
  var fruits = ["Apple", "Orange", "Pears"];
  var veggiesAndFruits = veggies.concat(fruits);
  console.log(veggiesAndFruits); // Tomato, Carrot, Cabbage, Apple, Orange, Pears



345.浅拷贝和深拷贝有什么区别?

有两种方法可以复制对象,

浅拷贝
浅拷贝是对象的按位拷贝。创建一个新对象,该对象具有原始对象中值的精确副本。如果对象的任何字段是对其他对象的引用,则仅复制引用地址,即仅复制内存地址。

例子

 var empDetails = {
   name: "John", age: 25, expertise: "Software Developer"
 }

创建副本

 var empDetailsShallowCopy = empDetails    //Shallow copying!

如果我们像这样更改重复项中的某些属性值:

 empDetailsShallowCopy.name = "Johnson"

上面的语句也会改变 的名称empDetails,因为我们有一个浅拷贝。这意味着我们也会丢失原始数据。

深拷贝
深拷贝复制所有字段,并复制这些字段指向的动态分配的内存。当一个对象与其所引用的对象一起被复制时,就会发生深度复制。

例子

 var empDetails = {
   name: "John", age: 25, expertise: "Software Developer"
 }

使用原始对象的属性创建一个深拷贝到新变量中

 var empDetailsDeepCopy = {
   name: empDetails.name,
   age: empDetails.age,
   expertise: empDetails.expertise }

现在,如果您更改 empDetailsDeepCopy.name,它只会影响 empDetailsDeepCopy 而不会影响empDetails



346.你如何创建一个字符串的特定数量的副本?

repeat()方法用于构造和返回一个新字符串,该字符串包含调用它的字符串的指定数量的副本,并连接在一起。请记住,此方法已添加到 ECMAScript 2015 规范中。

我们以Hello字符串为例,重复4次,

'Hello'.repeat(4);  // 'HelloHelloHelloHello'



347.你如何根据正则表达式返回所有匹配的字符串?

该matchAll()方法可用于返回与正则表达式匹配字符串的所有结果的迭代器。例如,下面的示例根据正则表达式返回匹配字符串结果的数组,

let regexp = /Hello(\d?))/g;let greeting = 'Hello1Hello2Hello3';let greetingList = [...greeting.matchAll(regexp)];console.log(greetingList[0]); //Hello1console.log(greetingList[1]); //Hello2console.log(greetingList[2]); //Hello3



348.你如何在开头或结尾修剪字符串?

trim字符串原型的方法用于修剪字符串的两侧。但是如果你想修剪特别是在字符串的开头或结尾,那么你可以使用trimStart/trimLeft和trimEnd/trimRight方法。让我们在问候消息中查看这些方法的示例,

var greeting = '   Hello, Goodmorning!   ';console.log(greeting); // "   Hello, Goodmorning!   "console.log(greeting.trimStart()); // "Hello, Goodmorning!   "console.log(greeting.trimLeft()); // "Hello, Goodmorning!   "console.log(greeting.trimEnd()); // "   Hello, Goodmorning!"console.log(greeting.trimRight()); // "   Hello, Goodmorning!"



349.下面带有一元运算符的控制台语句的输出是什么?

让我们使用一元运算符来执行控制台语句,如下所示,

console.log(+ 'Hello');

上述控制台日志语句的输出返回 NaN。因为元素以一元运算符为前缀,JavaScript 解释器会尝试将该元素转换为数字类型。由于转换失败,语句的值导致 NaN 值。



350.javascript 是否使用 mixins?

使用了,mixin在javascript里可以看作是一种从别的对象"借用"功能的方法。每一个新定义的对象都有一个 prototype属性,其他的对象就可以从这里"借用"功能。这里的功能可以是一个属性,也可以是一个方法。



351.什么是 thunk 函数?

thunk 只是一个延迟评估值的函数。它不接受任何参数,而是在您调用 thunk 时给出值。即,它用于现在不执行,但将来某个时候执行。让我们举一个同步的例子,

const add = (x,y) => x + y;const thunk = () => add(2,3);thunk() // 5



352.什么是异步 thunk?

异步 thunk 可用于发出网络请求。让我们看一个网络请求的例子,

function fetchData(fn){
  fetch('https://jsonplaceholder./todos/1')
  .then(response => response.json())
  .then(json => fn(json))}const asyncThunk = function (){
   return fetchData(function getData(data){
      console.log(data)
  })}asyncThunk()

该getData函数不会立即被调用,但只会在数据从 API 端点可用时调用。setTimeout 函数也用于使我们的代码异步。最好的实时示例是 redux 状态管理库,它使用异步 thunk 来延迟要调度的操作。



353.以下函数调用的输出是什么?

代码片段

const circle = {
  radius: 20,
  diameter() {
    return this.radius * 2;
  },
  perimeter: () => 2 * Math.PI * this.radius};console.log(circle.diameter());console.log(circle.perimeter());

输出:

输出是 40 和 NaN。请记住,直径是一个正则函数,而周长的值是一个箭头函数。this常规函数的关键字(即diameter)指的是周围的作用域,它是一个类(即Shape对象)。而perimeter函数的这个关键字是指周围的范围,它是一个窗口对象。由于窗口对象没有半径属性,它返回一个未定义的值,而数值的倍数返回 NaN 值。



354.如何从字符串中删除所有换行符?

最简单的方法是使用正则表达式来检测和替换字符串中的换行符。在这种情况下,我们使用替换函数和要替换的字符串,在我们的例子中是一个空字符串。

function remove_linebreaks( var message ) {
    return message.replace( /[\r\n]+/gm, "" );}

在上面的表达式中,g 和 m 用于全局和多行标志。



355.回流和重绘有什么区别?

甲重绘更改时,其影响的元件的可见性,而不是它的布局发生。这方面的示例包括轮廓、可见性或背景颜色。甲回流涉及影响页面(或整页)的一部分的布局的变化。调整浏览器窗口大小、更改字体、更改内容(例如用户键入文本)、使用涉及计算样式的 JavaScript 方法、从 DOM 中添加或删除元素以及更改元素的类是一些可以触发回流的事情。元素的回流会导致所有子元素和祖先元素以及 DOM 中跟随它的任何元素的后续回流。



356.否定数组会发生什么?

使用!字符否定数组将强制数组为布尔值。由于数组被认为是真实的所以否定它会返回false。

console.log(![]); // false



357.如果我们添加两个数组会发生什么?

如果将两个数组相加,它会将它们都转换为字符串并将它们连接起来。例如,添加数组的结果如下,

console.log(['a'] + ['b']);  // "ab"console.log([] + []); // ""console.log(![] + []); // "false", because ![] returns false.



358.在假值上添加加法运算符的输出是什么?

如果在假值(null、undefined、NaN、false、“”)上添加加法(+)运算符,则假值将转换为数字值零。让我们在浏览器控制台上显示它们,如下所示,

console.log(+null); // 0console.log(+undefined);// NaNconsole.log(+false); // 0console.log(+NaN); // NaNconsole.log(+""); // 0



359.如何使用特殊字符创建自字符串?

self 字符串可以由!+字符组合形成。您需要记住以下约定才能实现此模式。

由于数组是真实值,否定数组将产生错误: ![] === false
根据 JavaScript 强制规则,将数组相加在一起会将它们串起来: [] + [] === ""
在数组前面加上 + 运算符会将数组转换为假,否定将使其为真,最后转换结果将产生值 '1’: +(!(+[])) === 1
通过应用上述规则,我们可以得出以下条件

![] + [] === "false"+!+[] === 1

现在字符模式将被创建如下,

     s               e               l               f^^^^^^^^^^^^^   ^^^^^^^^^^^^^   ^^^^^^^^^^^^^   ^^^^^^^^^^^^^(![] + [])[3] + (![] + [])[4] + (![] + [])[2] + (![] + [])[0]^^^^^^^^^^^^^   ^^^^^^^^^^^^^   ^^^^^^^^^^^^^   ^^^^^^^^^^^^^(![] + [])[+!+[]+!+[]+!+[]] +(![] + [])[+!+[]+!+[]+!+[]+!+[]] +(![] + [])[+!+[]+!+[]] +(![] + [])[+[]]^^^^^^^^^^^^^^^^^^^^^^^^^^^^^(![]+[])[+!+[]+!+[]+!+[]]+(![]+[])[+!+[]+!+[]+!+[]+!+[]]+(![]+[])[+!+[]+!+[]]+(![]+[])[+[]]



360.如何从数组中删除虚假值?

您可以通过将布尔值作为参数传递来对数组应用过滤器方法。通过这种方式,它会从数组中删除所有虚假值(0、未定义、空值、假和“”)。

const myArray = [false, null, 1,5, undefined]myArray.filter(Boolean); // [1, 5] // 与 myArray.filter(x => x) 相同;



361.你如何获得数组的唯一值?

您可以使用Set和 rest /spread(…) 语法的组合来获取数组的唯一值。

console.log([...new Set([1, 2, 4, 4, 3])]); // [1, 2, 4, 3]



362.什么是解构别名?

有时,您希望解构变量的名称与属性名称不同。在这种情况下,您将使用 a: newName来指定变量的名称。这个过程称为解构别名。

const obj = { x: 1 };// 抓取 obj.x 作为 { otherName }const { x: otherName } = obj;



363.如何在不使用 map 方法的情况下映射数组值?

map只用fromArray的方法就可以不使用方法映射数组值。让我们从国家数组映射城市名称,

const countries = [
   { name: 'China', capital: 'Beijing' },
   { name: 'India', capital: 'Delhi' },
   { name: 'US', capital: 'Washington' },
   { name: 'Russia', capital: 'Moscow' },
   { name: 'Singapore', capital: 'Singapore' },
   { name: 'France', capital: 'Paris' },];const cityNames = Array.from(countries, ({ capital}) => capital);console.log(cityNames); // ['Beijing', 'Washington', 'Moscow', 'Singapore', 'Delhi', 'Paris']



364.你如何清空一个数组?

您可以通过将数组长度设置为零来快速清空数组。

let cities = ['Singapore', 'Delhi', 'London'];cities.length = 0; // cities becomes []



365.你如何将数字四舍五入到某些小数?

您可以使用toFixed原生 javascript 中的方法将数字四舍五入到一定数量的小数。

let pie = 3.141592653;pie = pie.toFixed(3); // 3.142



366.将数组转换为对象的最简单方法是什么?

您可以使用 spread(…) 运算符将数组转换为具有相同数据的对象。

var fruits = ["banana", "apple", "orange", "watermelon"];var fruitsObject = {...fruits};console.log(fruitsObject); // {0: "banana", 1: "apple", 2: "orange", 3: "wate



367.你如何用一些数据创建一个数组?

您可以使用fill方法创建具有某些数据的数组或具有相同值的数组。

var newArray = new Array(5).fill("0");console.log(newArray); // ["0", "0", "0", "0", "0"]



368.控制台对象的占位符是什么?

以下是控制台对象可用的占位符列表,

%o — 它需要一个对象,
%s — 它需要一个字符串,
%d — 用于十进制或整数 这些占位符可以在 console.log 中表示如下

const user = { "name":"Haiyong", "id": 1, "city": "Beijing"};console.log("Hello %s, your details %o are available in the object form", "John", user); // Hello Haiyong, your details {name: "Haiyong", id: 1, city: "Beijing"} are available in object



369.是否可以将 CSS 添加到控制台消息?

可以,您可以将 CSS 样式应用于类似于网页上的 html 文本的控制台消息。

console.log('%c 文本为蓝色,大字体和红色背景', 'color: blue; font-size: x-large; background: red');

文本将显示如下,
在这里插入图片描述

注意:所有 CSS 样式都可以应用于控制台消息。



370.控制台对象的dir方法的目的是什么?

console.dir()用于显示指定的JavaScript对象作为JSON的属性的交互式列表。

const user = { "name":"Haiyong", "id": 1, "city": "Beijing"};console.dir(user);

在这里插入图片描述

以 JSON 表示形式显示的用户对象



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 approachif (input === 'first' || input === 1 || input === 'second' || input === 2) {
 someFunction();}// Shortcutif (['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 FFconst 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 有什么区别?

表格形式的一些主要区别

promisesobservables
一次只发出一个值在一段时间内发出多个值(从 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); // 5array.length = 2;console.log(array.length); // 2console.log(array); // [1,2]

数组也可以清空

var array = [1, 2, 3, 4, 5];array.length = 0;console.log(array.length); // 0console.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(); // ReferenceErrorclass User {}

构造函数:

const user = new User(); // No errorfunction User() {}



407.什么是异步函数?

异步函数是一个用async关键字声明的函数,它可以通过避免承诺链以更简洁的风格编写异步的、基于承诺的行为。这些函数可以包含零个或多个await表达式。

让我们看一个下面的异步函数示例,

async function logger() {

 let data = await fetch('http:///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)) // falseconsole.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 newMyfunc(); // not called with newMyfunc.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’);   // trueNumber.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



我已经写了很长一段时间的技术博客,并且主要通过CSDN发表,这是我的一篇面试题文章。希望你们会喜欢!

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多