【面试题】JavaScript基础高频面试(下)

 10、Javascript 闭包是什么,闭包形成的原因和闭包的用途 ?

闭包(Closure)是 JavaScript 中的一个非常重要的概念。简单地说,闭包就是一个函数能够访问另一个函数的作用域。这是因为在 JavaScript 中,函数是一等公民,可以作为参数传递,也可以作为返回值返回。当一个函数 A 返回另一个函数 B,并且这个函数 B 中使用了函数 A 的变量,那么这时候就产生了闭包。

闭包形成的原因主要是因为 JavaScript 的词法作用域(lexical scoping)机制。词法作用域意味着函数的作用域在函数定义的时候就已经确定了,而不是在函数调用的时候确定。因此,即使外部函数已经返回,闭包依然能够访问外部函数的变量。

闭包的用途很广泛,主要有以下几点:

1. 模拟私有变量:在 JavaScript 中,我们没有真正意义上的私有变量,但我们可以通过闭包来模拟私有变量。例如:

```javascript
function createCounter() {
  let count = 0; // 这个变量在外部是无法访问的
  return function() {
    return ++count;
  };
}

let counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
```

在这个例子中,`count` 变量对于外部是不可见的,只有通过 `counter` 函数才能访问和修改。

2. 延长局部变量的生命周期:正常情况下,函数的局部变量在函数执行完之后就会被销毁。但是,如果我们创建了一个闭包,并且这个闭包引用了一些局部变量,那么这些局部变量就会一直存在,直到闭包被销毁。这可以用来保存函数的状态。

3. 实现某些设计模式,如模块模式(Module Pattern):使用闭包可以实现一个模块具有公开的方法和隐藏的私有方法或变量,这是模块模式的基础。

以上就是关于 JavaScript 闭包的一些基本解释和应用场景。希望对您有所帮助!

11、Javascript 跨域的解决方案有哪些?

跨域问题是由于浏览器的同源策略导致的。同源策略是一种约定,它是浏览器为了安全性而采取的策略,即浏览器要求所有的请求必须与当前页面的协议、主机名和端口号完全一致,否则就视为跨域。

解决跨域问题的常见方法有以下几种:

1. **JSONP**:JSONP 是一种常用的跨域数据交互的方法。它通过动态插入 script 标签来获取数据,因为 script 标签的 src 属性不受同源策略的限制。但是 JSONP 只能发送 GET 请求,且不安全。

2. **CORS**:跨源资源共享(CORS)是一种现代并且安全的跨域请求技术。服务器可以在响应头中添加一些 CORS 相关的头信息,如 `Access-Control-Allow-Origin`,来告诉浏览器允许特定的跨域请求。

3. **代理服务器**:通过服务器来转发请求和响应,因为服务器端没有同源策略的限制。例如,在 Node.js 中,我们可以使用 http-proxy-middleware 这样的中间件来实现。

4. **使用 WebSocket**:WebSocket 是一种通讯协议,不受同源策略的限制,可以用来实现跨域通信。

5. **使用 postMessage API**:HTML5 引入的 postMessage API 可以实现跨域通信。两个窗口(或者 iframe 和其父窗口)可以通过 postMessage 和 onmessage 实现数据的传递。

6. **使用 document.domain**:这种方法只能用于二级域名相同的情况。

7. **使用 window.name**:window 对象有一个 name 属性,这个属性在页面跳转时不会改变,可以通过它来传递数据。

8. **使用 location.hash**:通过改变 URL 的 hash(# 后面的部分)来传递数据,这种方法通常用于 iframe 间的通信。

以上就是一些常见的解决跨域问题的方法,具体使用哪一种方法,需要根据具体的应用场景和需求来决定。

12、Http协议详解 Http请求方式有 Http响应状态码 ?

**HTTP协议**:HTTP(HyperText Transfer Protocol)是一种无状态的、应用层的协议,主要用于在用户端(通常是 Web 浏览器)和服务器端之间传输数据。HTTP 是基于 TCP/IP 协议的,它通过请求和响应的方式来进行通信。

**HTTP 请求方法**:HTTP 定义了一组请求方法,也被称为“动词”,用来描述对资源的不同操作:

1. **GET**:获取资源。
2. **POST**:提交数据,通常会改变服务器的状态。
3. **PUT**:更新资源。
4. **DELETE**:删除资源。
5. **HEAD**:类似于 GET,但是只返回 HTTP 头部信息,不返回实体内容。
6. **OPTIONS**:获取资源支持的操作类型。
7. **PATCH**:对资源进行部分修改。

**HTTP 响应状态码**:HTTP 响应状态码用来表示服务器对请求的处理结果。常见的有:

1. **1xx(信息响应)**:表示请求已被接收,需要继续处理。
2. **2xx(成功)**:表示请求已成功被服务器接收、理解、并接受。
   - 200 OK:请求成功。
3. **3xx(重定向)**:需要后续操作才能完成请求。
   - 301 Moved Permanently:资源永久性转移。
   - 302 Found:资源临时性转移。
4. **4xx(客户端错误)**:表示请求含有语法错误或者无法被服务器执行。
   - 400 Bad Request:请求语法错误。
   - 401 Unauthorized:请求需要认证。
   - 403 Forbidden:服务器拒绝请求。
   - 404 Not Found:请求的资源无法找到。
5. **5xx(服务器错误)**:表示服务器在处理请求的过程中发生了错误。
   - 500 Internal Server Error:服务器内部错误。
   - 503 Service Unavailable:服务器暂时无法处理请求。

13、JavaScript什么是长连接 ?

长连接(也被称为持久连接、keep-alive连接或者连接保持)是一种通信机制,它允许客户端和服务器在一个连接上发送多个请求和响应,而不需要为每个请求/响应对创建新的连接。这种机制可以显著地降低服务器的负载,提高资源的使用率。

在 HTTP/1.0 中,每一个 HTTP 请求/响应对都需要建立一个新的 TCP 连接,这会带来很大的开销。而在 HTTP/1.1 中,引入了长连接的概念,允许在一个连接上进行多次 HTTP 交互,直到客户端或者服务器主动关闭连接。

在 JavaScript 中,我们可以使用 XMLHttpRequest 或 Fetch API 发送 HTTP 请求,它们默认都会使用长连接。此外,我们还可以使用 WebSocket 或 Server-Sent Events 来实现真正的双向长连接,这两种技术都允许服务器主动向客户端推送数据。

例如,WebSocket 可以用来实现实时聊天、多人游戏、实时数据更新等功能。在这些场景中,服务器需要能够随时向客户端推送新的数据,而不需要客户端每次都发送请求。WebSocket 通过在客户端和服务器之间建立一个持久的、全双工的连接,使得数据可以在任何时间点从任一方向传输。

14、display:none和visibility:hidden的区别是 ?

`display: none` 和 `visibility: hidden` 都可以用来隐藏 HTML 元素,但是它们之间有一些重要的区别:

1. **空间占用**:当元素被设置为 `display: none` 时,这个元素会从文档流中完全移除,就像它从来没有存在过一样。它不会占据任何空间,也不会影响到其他元素的布局。而当元素被设置为 `visibility: hidden` 时,这个元素虽然不可见,但是它依然会占据空间,依然会参与布局。

2. **对子元素的影响**:`display: none` 会影响到元素的所有子元素,如果一个元素被设置为 `display: none`,那么它的所有子元素也都会被隐藏,无论子元素的 `display` 属性是什么。而 `visibility: hidden` 不会影响到子元素的 `visibility` 属性,也就是说,如果一个元素被设置为 `visibility: hidden`,它的子元素依然可以通过设置 `visibility: visible` 来显示。

3. **对事件的影响**:被设置为 `display: none` 的元素不会响应任何事件,例如鼠标点击事件。而被设置为 `visibility: hidden` 的元素依然可以响应事件,例如,即使一个按钮被设置为 `visibility: hidden`,用户依然可以通过 Tab 键导航到这个按钮,并使用 Enter 键来触发点击事件。

以上就是 `display: none` 和 `visibility: hidden` 的主要区别。总的来说,`display: none` 更像是“删除”元素,而 `visibility: hidden` 更像是“隐藏”元素。

15、JavaScript中常用的数组方法?

JavaScript 中的数组有许多内置的方法可以帮助我们操作数组。以下是一些常用的数组方法:

1. **push()**:在数组的末尾添加一个或多个元素,并返回新的长度。

```javascript
let arr = ['a', 'b', 'c'];
arr.push('d'); // 返回 4
console.log(arr); // 输出 ['a', 'b', 'c', 'd']
```

2. **pop()**:删除并返回数组的最后一个元素。

```javascript
let arr = ['a', 'b', 'c'];
let last = arr.pop(); // 返回 'c'
console.log(arr); // 输出 ['a', 'b']
```

3. **shift()**:删除并返回数组的第一个元素。

```javascript
let arr = ['a', 'b', 'c'];
let first = arr.shift(); // 返回 'a'
console.log(arr); // 输出 ['b', 'c']
```

4. **unshift()**:在数组的开头添加一个或多个元素,并返回新的长度。

```javascript
let arr = ['a', 'b', 'c'];
arr.unshift('0'); // 返回 4
console.log(arr); // 输出 ['0', 'a', 'b', 'c']
```

5. **splice()**:在数组中添加或删除元素。

```javascript
let arr = ['a', 'b', 'c'];
arr.splice(1, 0, 'x'); // 在索引为1的位置插入'x'
console.log(arr); // 输出 ['a', 'x', 'b', 'c']
```

6. **slice()**:返回一个新的数组,包含从 start 到 end(不包括 end)的数组元素。

```javascript
let arr = ['a', 'b', 'c', 'd', 'e'];
let newArr = arr.slice(1, 3); // 返回 ['b', 'c']
```

7. **sort()**:对数组的元素进行排序。

```javascript
let arr = ['c', 'a', 'b'];
arr.sort(); 
console.log(arr); // 输出 ['a', 'b', 'c']
```

8. **reverse()**:颠倒数组中元素的顺序。

```javascript
let arr = ['a', 'b', 'c'];
arr.reverse();
console.log(arr); // 输出 ['c', 'b', 'a']
```

9. **join()**:将所有的数组元素连接成一个字符串。

```javascript
let arr = ['a', 'b', 'c'];
let str = arr.join('-'); // 返回 'a-b-c'
```

10. **map()**:创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。

```javascript
let arr = [1, 2, 3];
let newArr = arr.map(x => x * 2); // 返回 [2, 4, 6]
```

11. **filter()**:创建一个新数组, 其包含通过所提供函数实现的测试的所有元素。

```javascript
let arr = [1, 2, 3, 4, 5];
let newArr = arr.filter(x => x > 3); // 返回 [4, 5]
```

12. **reduce()**:对数组中的每个元素执行一个由您提供的 reducer 函数(升序执行),将其结果汇总为单个返回值。

```javascript
let arr = [1, 2, 3, 4, 5];
let sum = arr.reduce((acc, cur) => acc + cur, 0); // 返回 15
```

以上就是 JavaScript 中常用的数组方法。

16、手写防抖、节流,防抖和节流的区别 ?

**防抖(debounce)**:如果一个函数持续地触发,那么只在它停止触发的一段时间后才执行,如果在这段时间内又开始持续触发,则重新计算时间。

防抖函数的实现如下:

```javascript
function debounce(func, wait) {
  let timeout;
  return function() {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      func.apply(this, arguments);
    }, wait);
  };
}
```

**节流(throttle)**:如果一个函数持续地触发,那么固定在一段时间内只执行一次。

节流函数的实现如下:

```javascript
function throttle(func, wait) {
  let lastTime = 0;
  return function() {
    let now = Date.now();
    if (now - lastTime > wait) {
      func.apply(this, arguments);
      lastTime = now;
    }
  };
}
```

**防抖和节流的区别**:

- 防抖是让连续触发的函数在一段时间后只执行一次,如果在这段时间内又触发了该函数,则重新计算时间。适用场景:文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证一次就好)。
- 节流是让连续触发的函数在一段时间内只执行一次,并且这段时间内的多次触发只会计算一次。适用场景:滚动加载,时间间隔内只加载一次,模拟鼠标移动(mousemove),监听滚动事件(比如是否滑到底部自动加载更多,用 throttle 是为了降低频率)。

17、Javascipt的call和apply的区别 ?

`call` 和 `apply` 都是 Function 对象的方法,它们都可以用来改变函数的 `this` 上下文并立即调用这个函数。它们的主要区别在于参数的传递方式:

1. **call** 方法接受的是参数列表,第一个参数是 `this` 的值,之后是传递给函数的参数。例如:

```javascript
function greet(name, age) {
  console.log(`Hello, my name is ${name} and I am ${age} years old.`);
}

greet.call(, 'Alice', 25);  // 输出 "Hello, my name is Alice and I am 25 years old."
```

2. **apply** 方法接受的是一个参数数组,第一个参数同样是 `this` 的值,第二个参数是一个数组,其中包含了传递给函数的参数。例如:

```javascript
function greet(name, age) {
  console.log(`Hello, my name is ${name} and I am ${age} years old.`);
}

greet.apply(, ['Alice', 25]);  // 输出 "Hello, my name is Alice and I am 25 years old."
```

在 ES6 中,你还可以使用扩展运算符(spread operator)和 `apply` 达到和 `call` 相同的效果:

```javascript
greet.apply(, ['Alice', 25]);  // 使用 apply
greet(...['Alice', 25]);  // 使用扩展运算符,效果和上面一样
```

总的来说,`call` 和 `apply` 的功能是相同的,只是参数的传递方式不同。你可以根据实际需求选择使用哪一个。

18、JavaScript 闭包是什么,有什么特性,对页面有什么影响?简要介绍你理解的闭包?

闭包是JavaScript中一种非常重要的概念,它的定义可能有点抽象:闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见方式就是在一个函数内部创建另一个函数。

闭包的特性主要包括以下几点:

1. 函数嵌套:外部函数中嵌套内部函数,内部函数可以访问外部函数的变量和参数。
2. 变量引用:即使外部函数已经返回,内部函数仍然可以引用外部函数的变量和参数。
3. 内存消耗:由于内部函数保持了对外部函数变量的引用,所以这些变量不会被垃圾收集器回收,可能会导致内存消耗。

闭包的影响主要体现在以下几个方面:

1. 数据封装和私有成员:通过闭包,我们可以创建私有变量,防止外部访问,达到数据封装和保护的目的。
2. 持久化变量:闭包可以使得函数中的变量在函数执行完毕后仍然保存在内存中,可用于在不同函数调用间保持状态。

举个例子说明闭包:

```javascript
function outerFunction() {
    var count = 0;
    function innerFunction() {
        count++;
        console.log(count);
    }
    return innerFunction;
}

var instance = outerFunction();
instance();  // 输出:1
instance();  // 输出:2
```

在这个例子中,`outerFunction`返回了`innerFunction`,并且`innerFunction`引用了`outerFunction`的`count`变量。即使`outerFunction`已经执行完毕,但是由于`innerFunction`对`count`的引用,`count`变量仍然存在,每次调用`instance()`,`count`都会增加并打印出来。这就是闭包的一个典型的应用场景。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/17104.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle直接路径读解析

目录 一、直接路径读概念二、直接路径读在OLTP和OLAP环境中的不同点三、如何禁止直接路径读方法1:使用事件设置方法2:使用隐含参数 一、直接路径读概念 直接路径读(Direct Path Read)是Oracle数据库中的一种数据读取机制&#xf…

10编码(数据转化为信号)

目录 数据转化为信号 数字数据编码为数字信号: 数字数据调制为模拟信号: 模拟数据编码为数字信号: 模拟数据调制为模拟信号: 数据转化为信号 数据转化为数字信号要通过编码,转化为模拟信号通过调制 数据又分为数字…

PXI总线测试模块-6939 矢量信号发生器

频率范围:250kHz~6GHz 6939 矢量信号发生器 6939矢量信号发生器提供频率范围250kHz~6GHz的多制式信号,单边带相位噪声优于-120dBc/Hz10kHz(载波1GHz)、EVM优于1.0%,能够实现高纯连续波输出、模拟调制信号输…

Linux: network: TCP: zero window size/window full 示例

最近遇到一个问题,当前机器的CPU使用率非常高,然后导致其中一个程序处理socket的数据过慢,然后出现下面的zero的示例。 下面是在接收buff用光的时候,发出的 TCP zeroWindows的消息 这种问题就是内存,CPU,网速之间的性能取舍。具体解决的话,需要看具体的需要是什么样的?…

参数高效微调PEFT(一)快速入门BitFit、Prompt Tuning、Prefix Tuning

参数高效微调PEFT(一)快速入门BitFit、Prompt Tuning、Prefix Tuning 目前,模型最全的网站是HuggingFace,但是国内需要魔法流量才能访问。另外,现在大模型权重文件都较大,也会浪费不少流量,因此这里推荐使用魔搭社区下…

Spring+SpringBoot面试总结(近两万字)

SpringSpringBoot面试总结 一、Spring Bean1.1、bean的生命周期(对象的创建使用销毁)1.1.1、准备工作1.1.2、创建Bean对象1.1.3、注册销毁 1.2、 bean的作用域1.2.1、配置方式 1.3、 spring 自动装配 bean 有哪些方式(存疑存疑)1.…

2024年上半年软件设计师试题及答案(回忆版)--案例题

案例题 1.缺陷识别的数据流图 摄像机原始图像 缺陷识别,特征值,颜色、纹理,是否缺陷,缺陷类型 识别结果 数据导出,供检测识别系统模型积累、训练 系统管理,质量员配置系统参数 1.实体 2.存储 3.面向对象的分析与面向对象的设计2个阶段的模型区别 4.数据组成 2.球队、…

软件测试金字塔,对号入座,你在哪层?

自从学习了软件测试,脑袋也清晰了,目标也明确了,就是不知道学到哪里了.中间有很多的困难也有很多成就感,你目前在那个阶段呢? 初级测试工程师 技能要求:需求分析,使用等价类边界值等方法进行用例设计,执行功能测试,发现提交跟踪bug,使用禅道,会在测试中会操作数据库进行检查和…

数学建模--LaTeX的基本使用

目录 1.回顾 2.设置这个页眉和页脚 3.对于字体的相关设置 4.对于这个分级标题的设置 5.列表的使用 6.插入图片 1.回顾 (1)昨天我们了解到了这个latex的使用基本常识,以及这个宏包的概念,区域的划分,不同的代码代…

电磁仿真--CST综合建模练习1

1. 简介 本文展示一个CST自带的示例,在三维空间中使用带线计算传输线的S参数。基板顶部的带线通过小圆柱连接到底部的短带线,以便绕过可能存在的障碍。 结构生成 该结构完全通过参数输入进行建模,参考波长为10毫米,因此可以轻松…

JavaWeb开发 1.Web开发 介绍

我的生命是一万次的春和景明 —— 24.5.27 一、什么是Web Web: 全球广域网,也称为万维网(www World Wide Web),能够通过浏览器访问的网站 Web网站的工作流程 学习流程

kafka的安装

windows下kafka的安装 【Kafka】Windows下安装Kafka(图文记录详细步骤)_windows安装kafka-CSDN博客 kafka生产消息 kafka消费消息

​​​【收录 Hello 算法】10.6 小结

10.6 小结 二分查找依赖数据的有序性,通过循环逐步缩减一半搜索区间来进行查找。它要求输入数据有序,且仅适用于数组或基于数组实现的数据结构。暴力搜索通过遍历数据结构来定位数据。线性搜索适用于数组和链表,广度优先搜索和深度优先搜索…

指纹识别经典图书、开源算法库、开源数据库

目录 1. 指纹识别书籍 1.1《精通Visual C指纹模式识别系统算法及实现》 1.2《Handbook of Fingerprint Recognition》 2. 指纹识别开源算法库 2.1 Hands on Fingerprint Recognition with OpenCV and Python 2.2 NIST Biometric Image Software (NBIS) 3. 指纹识别开源数…

怎样确保后端系统的安全性和防止数据泄露?

确保后端系统的安全性和防止数据泄露是一个重要的任务,以下是一些常见的方法: 强化身份验证:使用强密码和多因素身份验证来确保只有授权的用户能够访问系统。 加密数据:对敏感数据进行加密,包括数据在传输和存储时都要…

TensorFlow常见任务训练

### 1. 手写体数字识别 (MNIST) python import tensorflow as tf from tensorflow.keras.datasets import mnist from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense, Flatten # 加载MNIST数据集 (x_train, y_train), (x_test, y_te…

【StableDiffusion】SD1.4、1.5、2.0、2.1 和 SDXL0.9-1.0、SDXL turbo 等的区别

总览 1.基础sd base model家族:SD1.4、SD1.5、SD1.5-LCM、SD2.0、SD2.0-768、SD2.1、SD2.1-768、SD2.1-UNCLIP 2.升级sdxl base model家族:SDXL0.9、SDXL1.0、SDXL1.0-LCM、SDXL-DISTILLED、SDXL-TURBO 3.专门用于视频生成的 SVD 家族:SVD、…

元对象系统

一、定义与基本概念 元对象系统是一个基于Qt框架的核心机制,它提供了运行时类型信息(RTTI)以及信号与槽(Signals and Slots)机制的支持。这个系统使得Qt能够实现许多强大的功能,如信号与槽的自动连接、QObject树结构的管理等。 二、主要特性与功能 运…

开启重学英语之路

为什么学了这么多年的英语还是不能自信的说自己擅长英语。 就算是在学校考了很高的分数,依然不能流利的和外国人对话。 只能说明之前的英语学习方法和学习思路只有问题的,所以不能一头扎进英语知识的学习之中,需要先反问自己一些问题&#…

C++习题(1)

一、题目描述&#xff1a; 二、代码展示&#xff1a; #include <iostream> #include <iomanip> using namespace std; struct Student{char name[20];int id;int age;float score; }; int main() {int n;cin>>n;Student student[n];float sum0.0;for(int i0…