JS基础知识篇

JS基础知识篇

1. js数组常用方法 哪些会改变原数组 遍历方法有哪些方式可以停止遍历?

首先说一下会改变原数组的方法有哪些:
push() 和 unshift():在数组末尾或开头添加元素。
pop() 和 shift():从数组末尾或开头删除元素。
splice():删除、替换或插入元素。
reverse():反转数组的顺序。
sort():对数组元素进行排序。
fill():用指定值填充数组的元素。
copyWithin():从数组内部复制元素到其他位置。
不会改变原数组的方法:
concat():合并多个数组,返回一个新数组。
join():将数组元素连接为字符串。
slice():返回选定的数组部分。
filter():返回符合条件的新数组。
map():根据函数对数组每个元素进行操作,返回新数组。
reduce() 和 reduceRight():从左/右累积数组元素。
every():检查数组所有元素是否满足条件。
some():检查数组是否有满足条件的元素。
find() 和 findIndex():查找数组中符合条件的第一个元素及其索引。
includes():检查数组是否包含某个元素。
indexOf() 和 lastIndexOf():返回元素在数组中的索引。
toString() 和 toLocaleString():将数组转换为字符串。
遍历途中中止遍历:
使用原生的for循环遍历+break;

const numbers = [1, 2, 3, 4, 5];

for (let i = 0; i < numbers.length; i++) {
  if (numbers[i] === 3) {
    console.log("Found 3 at index:", i);
    break; // 停止遍历
  }
}

在some中中止遍历:

const numbers = [1, 2, 3, 4, 5];

numbers.some((value, index) => {
  if (value === 3) {
    console.log("Found 3 at index:", index);
    return true; // 停止遍历
  }
});

2.sort函数怎么从大到小排序
const numbers = [10, 5, 8, 2, 7];

// 使用比较函数将数组从大到小排序
numbers.sort((a, b) => b - a);

console.log(numbers); // 输出: [10, 8, 7, 5, 2]

如果 b - a 的值为负数,意味着 b 应该排在 a 前面,所以 a 和 b 的位置会交换。
如果 b - a 的值为零,意味着 a 和 b 相等的顺序不需要改变。
如果 b - a 的值为正数,意味着 b 应该排在 a 后面,所以它们的位置保持不变。

3.深拷贝和浅拷贝的方法有哪些

浅拷贝----------------
Object.assign(): Object.assign(target, …sources) 方法可以将一个或多个源对象的属性复制到目标对象中。这是浅拷贝,如果属性值是对象,则复制的是引用。

const source = { a: 1, b: { c: 2 } };
const shallowCopy = Object.assign({}, source);

Spread Operator(扩展运算符): 使用 … 扩展运算符也可以进行浅拷贝。

const source = { a: 1, b: { c: 2 } };
const shallowCopy = { ...source };

深拷贝-----------------------
递归方法: 递归地遍历对象的所有属性,对每个属性进行复制

function deepCopy(obj) {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  const copy = Array.isArray(obj) ? [] : {};

  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      copy[key] = deepCopy(obj[key]);
    }
  }

  return copy;
}

JSON.stringify() 和 JSON.parse(): 利用 JSON 序列化和反序列化可以实现深拷贝,但要注意它会忽略函数、循环引用等特殊情况

const source = { a: 1, b: { c: 2 } };
const deepCopy = JSON.parse(JSON.stringify(source));

4.es6 的new关键字 new 构造函数的时候this的指向改变四次 分别指向什么?

使用 new 关键字来创建对象实例时,this 的指向会经历四次变化。这四次变化可以用来解释构造函数内部的执行过程。下面是这四次变化的具体情况:
①创建一个新对象: 当你使用 new 关键字调用构造函数时,首先会创建一个新的空对象。
②将新对象的原型链链接到构造函数的原型对象: 新对象会继承构造函数的原型对象上的属性和方法。
③将构造函数的作用域赋给新对象的 this: 此时,构造函数内部的代码会在新对象的上下文中执行,构造函数中的 this 指向新创建的对象。
④返回新对象: 如果构造函数没有显式返回其他对象,则返回新创建的对象

5. 数字千分位展示
const number = 1234567.89;
const formattedNumber = number.toLocaleString();
console.log(formattedNumber); // 输出: "1,234,567.89"

6.ES6模块化原理

ES6 模块化基于两个主要概念:导入(import)和导出(export)。
导出(export): 在一个模块中,使用 export 关键字将变量、函数、类等导出,使它们能够在其他模块中使用。

// example.js

export const name = "John";
export function sayHello() {
  console.log("Hello!");
}

导入(import): 在另一个模块中,你可以使用 import 关键字来引入其他模块导出的内容。

// app.js

import { name, sayHello } from './example.js';

console.log(name); // 输出: "John"
sayHello(); // 输出: "Hello!"

模块之间的连接: 当一个模块导入另一个模块时,JavaScript 引擎会自动执行被导入模块的代码,并且返回被导出的内容,使其在导入模块中可用。
静态解析: ES6 模块化是静态解析的,这意味着模块的依赖关系在代码被执行之前就可以确定。这有助于提高性能和可维护性。
单一实例: 每个模块在应用中只会被加载和执行一次,无论在多少地方导入它。这确保了模块的单一实例性质。
默认导出和导入: 除了命名导出,ES6 还支持默认导出和导入。默认导出可以是任何值,而不仅限于变量或函数。

7. commonJS和ES模块化区别

CommonJS 模块化:
用法: CommonJS 最初是为服务器端开发而设计的,主要在 Node.js 中使用。在 CommonJS 中,模块的加载是同步的,模块被执行后,它的输出会被缓存,后续引用直接使用缓存的值。
导入和导出: 使用 require 来导入模块,使用 module.exports 导出模块。
动态加载: CommonJS 允许在运行时动态加载模块,这使得模块的加载可以根据条件进行。
运行时执行: 模块的代码在导入时会被执行,因此适用于同步加载和运行的场景。
ES6 模块化:
用法: ES6 模块化是 JavaScript 标准库的一部分,可以在现代浏览器中使用,也可以在 Node.js 中使用。在 ES6 模块化中,模块的加载是异步的,加载后会生成一个只读引用。
导入和导出: 使用 import 来导入模块,使用 export 导出模块。
静态加载: ES6 模块化在编译阶段就确定了模块的依赖关系,使得代码更容易静态分析和优化。
编译时执行: 模块的代码在导入时不会立即执行,而是在被需要时按需执行,适用于异步加载的场景。
默认导出和导入: ES6 模块化支持默认导出和导入,使得在导入时可以更加灵活。

对于上面两者的执行时机,再做一下解释:
在 CommonJS 中,模块的代码在导入时立即执行,输出被缓存,后续导入直接使用缓存。
在 ES6 模块化中,模块的代码在导入时不会立即执行,只有在实际使用时才会被执行,导入的代码会被标记以便于后续执行。

8. async和await区别

async 和 await 是 JavaScript 中用于处理异步操作的关键字,它们一起工作,使异步代码的编写和理解更加简洁和直观。下面是它们的主要区别:
async:
async 关键字用于声明一个函数是异步的,即使函数内部有同步的代码,也会被视为异步函数。
异步函数会隐式地返回一个 Promise 对象,这个 Promise 对象的状态和值会根据函数内部的执行结果进行设置。

async function fetchData() {
  return 'Data fetched'; // 返回一个 Promise,状态为已解决,并携带值 'Data fetched'
}

await:
await 关键字用于等待一个 Promise 对象的解决状态,只能在异步函数内部使用。
当遇到 await 时,函数会暂停执行,直到 Promise 对象的状态变为已解决,并返回解决的值。

async function fetchData() {
  const data = await fetchDataFromServer(); // 等待 fetchDataFromServer() 的 Promise 解决
  console.log(data);
}

总结:
async 关键字用于声明异步函数,返回一个 Promise。
await 关键字用于等待 Promise 的解决状态,只能在异步函数内部使用,使代码执行等待异步操作完成。
需要注意的是,在使用 await 时,必须将它放在异步函数内部,以便正确地等待和处理异步操作。

9.如果在const之前使用了变量会出现什么?

看下面的代码:

let x = 10;
const y = x + 5;
console.log(y); 

上面的代码正常输出15,不会报错!!
解释:const 关键字声明的常量确实需要在声明时进行赋值,但在 const 声明之前使用变量进行赋值或操作是没有问题的,不会导致语法错误。

10. async和defer在js加载的时候区别

async 和 defer 是用于控制外部 JavaScript 文件加载和执行时机的两个属性。它们可以在

<script src="script.js" async></script>

defer 属性:
当使用 defer 属性时,浏览器会异步加载脚本,但会等待 HTML 解析完成后再执行脚本。
脚本的执行时机是在 DOMContentLoaded 事件之前,保证脚本能够访问和操作 DOM。
适用于需要等待整个文档解析完毕才执行的脚本,可以操作 DOM。

<script src="script.js" defer></script>

总结:
async 属性用于异步加载并立即执行脚本,执行时机不确定。
defer 属性用于异步加载脚本,并在整个文档解析完成后执行,执行时机在 DOMContentLoaded 事件之前。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值