33.JS测试题

5/13/2023 js

# 1.实现一个方法,从某个数值数组中,获取最小正数(非零非负数)的索引值

const findNonZeroMinIndex = (arr) => {
    let min = Infinity
    let index = -1
    for(var i = 0; i < arr.length; i++) {
        if(arr[i] > 0 && arr[i] < min) {
            min = arr[i]
            index = i
            console.log('---', min, index)
        }
    }
    return index
}
a = [9, 0, 2, 33, -20, 10]
findNonZeroMinIndex(a)
// 使用循环和条件判断来遍历数组,查找满足条件(即非零非负数)并且值最小的元素,并返回其索引。
// 如果数组中没有满足条件的元素,则返回 -1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 2.实现一个等待函数,支持让async函数在执行时暂停一段时间,函数的入参为暂停的时间

const wait = (timer) => {
    return new Promise((resolve) => setTimeout(resolve, timer))
}
const test = async () => {
    console.log('start')
    await wait(1000)
    console.log('end')
}
test()
// 在使用 async/await 时,可以用 await 关键字等待一个 Promise 对象的结果,然后执行一些操作。在等待过程中,函数会暂停执行,直到 Promise 对象的状态发生改变。
1
2
3
4
5
6
7
8
9
10

# 3.使用正则表达式实现以下需求:筛选出数组中只包含大小写字母的字符串,并将结果转换成大写

const arr = ['Abc', 'DeF', '123', '_ghI'];
const filteredArr = arr.filter(item => /^[a-zA-Z]+$/.test(item))
        .map(item => item.toUpperCase());
console.log(filteredArr); // ["ABC", "DEF"]
// 可以先使用正则表达式 /^[a-zA-Z]+$/ 来匹配只包含大小写字母的字符串,使用 Array.prototype.filter() 方法来筛选符合条件的元素,然后使用 Array.prototype.map() 方法将每个元素转换成大写,最终得到了一个新的数组 filteredArr
1
2
3
4
5

# 4.请补充objToArray函数

/**
 * @file objToArray
 *
 * 将对象按照要求转为数组
 * 注意console示例运行结果
 */
type Obj = Record<string, string>;
interface FormatItem {
  key: string;
  op: string;
  value: string;
}

function objToArray(obj: Record<string, Obj>): FormatItem[] {
  // 补全此处代码
  throw new Error("功能待实现");
}

console.log(
  objToArray({
    key1: {
      op1: "value1",
    },
    key2: {
      op2: "value2",
    },
  })
);
// result示例
// [
//     {key: 'key1', op: 'op1', value: 'value1'},
//     {key: 'key2', op: 'op2', value: 'value2'}
// ]

export default {};

// 补全objToArray函数
const objToArray = (obj) => {
  return Object.keys(obj).reduce((value, key) => {
    op = Object.keys(Object.keys(obj))[0]
    value.push({key: key, op: op, value: obj[key][op] })
    return value
  }, [])
}
objToArray(obj)

// reduce
reduce(callbackFn)
reduce(callbackFn, initialValue)
// callbackFn(previousValue, currentValue)
// 初始值:initialValue可选。若指定了初始值 initialValue,则 currentValue 则将使用数组第一个元素;否则 previousValue 将使用数组第一个元素,而 currentValue 将使用数组第二个元素。
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

# 5.实现一个将多维数组展示的方法

// 方法一: flat()
let arr = [1,2,3,[4,5],6];
let res = arr.flat();//[1,2,3,4,5,6]

let arr1 = [1,2,3,[4,5,[6,7]],8];
let res1 = arr.flat(3); //参数3代表三维数组的展开,结果为[1,2,3,4,5,6,7,8]
let arr2 = [1,2,3,[4,5,[6,7,[8]]],9];
let res2 = arr2.flat(4); //参数4代表思维数组的展开,结果为[1,2,3,4,5,6,7,8,9]

let arr3 = [1,2,3,[4,5,[6,7,[8]]],9];
let res3 = arr3.flat(Infinity); //参数为Infinity(对于未知数组维度),结果为[1,2,3,4,5,6,7,8,9]

// 方法二:扩展运算符
function flatten(arr){
  while(arr.some(item=>Array.isArray(item))){
    arr = [].concat(...arr);
  }
  return arr;
}
var sunArr = [1,2,3,[4,[5,[6]]]];
flatten(sunArr);//结果为 [1, 2, 3, 4, 5, 6]

// 方法三:
const test1 = (b) => {
const newArr = []
 const fun = (arr) => {
    arr.forEach(item => {
      if(Array.isArray(item)) {
         fun(item)
      } else {
         newArr.push(item)
      }
    })
 } 
  fun(b)
  return newArr
}
test1([1,2,3,[4,[5,[6]]]])
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

# 6.使用TS实现一个判断传入参数是否是数组类型的方法

function isArray(x: unknown): boolean {
  return Array.isArray(x)
}
1
2
3

# 7.如何实现一个new

使用new关键字可以创建一个新对象,并调用构造函数来初始化这个对象
new的定义是创建一个对象的示例,该对象继承了构造函数的原型,并将构造函数作为构造器来初始化这个对象

// 创建一个空对象,并继承构造函数的原型
// 调用构造函数,并将实例作为上下文
// 如果构造函数返回了一个对象,则返回改对象;否则返回新创建的实例
function _new(fn, ...arg) {
  const obj = Object.create(fn.prototype)
  const res = fn.apply(obj, arg)
  return res instanceof Object ? res : obj
}

function test(name) {
  this.name = name
}
test.prototype.say = function () {
  console.log('my name is '+ this.name)
}
const a = _new(test, 'zs')
a.say()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 8.两个数组合并成一个数组

const arr1 = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2', 'D1', 'D2']
const arr2 = ['A', 'B', 'C', 'D']
const res = [...a1, ...a2].sort((a, b) => {
  return a.charCodeAt() - b.charCodeAt()
})
// sort 方法参数为回调函数,该函数接受两个参数,表示进行比较的两个数组成员;
// 排序的规则为,如果该函数的返回值大于0,表示第一个成员排在第二个成员后面,
// 否则都是第一个成员排在第二个成员前面
1
2
3
4
5
6
7
8

# 9.改造下面的代码,使之输出0 - 9,写出你能想到的所有解法

for (var i = 0; i< 10; i++){
	setTimeout(() => {
		console.log(i);
    }, 1000)
}

// 方法一:
// setTimeout 函数的第三个参数,会作为回调函数的第一个参数传入
for (var i = 0; i< 10; i++){
	setTimeout(() => {
		console.log(i);
    }, 1000, i)
}

// 方法二:
// 利用let变量的特性,只在当前块级作用域里面生效
for (let i = 0; i< 10; i++){
	setTimeout(() => {
		console.log(i);
    }, 1000)
}
// 等价于
for (let i = 0; i < 10; i++) {
  let _i = i; // const _i = i;
  setTimeout(() => {
    console.log(_i);
  }, 1000)
}

// 方法三:
// 利用函数自执行的方式,把当前 for 循环过程中的 i 传递进去,构建出块级作用域
for (var i = 0; i< 10; i++){
	(
    (i) => {
      setTimeout(() => {
        console.log(i);
      }, 1000)
    }
  )(i)
}

// 方法四:
for (var i = 0; i < 10; i++) {
  setTimeout(console.log(i), 1000)
}

for (var i = 0; i < 10; i++) {
  setTimeout((() => {
    console.log(i);
  })(), 1000)
}

for (var i = 0; i < 10; i++) {
  setTimeout((i => {
    console.log(i);
  })(i), 1000)
}
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

# 10.下面代码a在什么情况下会打印1

var a = ?;
if(a == 1 && a == 2 && a == 3){
 	console.log(1);
}

// 考察类型的隐式转换,考察引用类型在比较运算符时候,隐式转换会调用本类型的toString或valueOf方法
let a = {
  i: 1,
  valueOf: () => {
    return a.i++
  }
}
if(a == 1 && a == 2 && a == 3){
 	console.log(1);
}

let a = {
  i: 1,
  toString () {
    return a.i++
  }
}

if(a == 1 && a == 2 && a == 3) {
  console.log('1');
}
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

# 11.实现一个sleep函数

// 异步方法
const sleep = (timer) => {
  return new Promise((resolve) => setTimeout(resolve, timer))
}

sleep(1000).then((res) => {
  console.log('123')
})

// 同步方法
const sleep = (timer) => {
  const _now = Date.now()
  while(Date.now() - _now < timer); 
}
sleep(1000)
console.log('333')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 11.下面代码打印什么内容

var b = 10;
(function b(){
  b = 20;
  console.log(b); 
})();
// 输出函数类型:ƒ b(){b = 20; console.log(b); }
// 立即执行函数创建一个新的函数作用域,使得其内部有独立的变量命名空间,并且这些变量不会影响外部环境。此时定义了一个函数名为b的函数,又在函数体内尝试将b变量赋值为数字20,但是由于此时b已经被作为函数名占用了,因此这里的b赋值操作就相当于对函数的重新赋值。这会导致当前这个函数对象的toString()方法返回的是函数的字符串形式ƒ b(){b = 20; console.log(b); }。接着,在函数体内部调用 console.log 输出变量 b,虽然本意是要输出变量的值,但是 JavaScript 引擎在查找到当前作用域内已经定义了一个名为 b 的函数时,就会返回该函数对象本身,而不是变量的值。
1
2
3
4
5
6
7

# 12.改造下面的代码,使之分别打印10、20

var b = 10;
(function b(){
  b = 20;
  console.log(b); 
})();


var b = 10;
(function b(){
  var b = 20; //or let b = 20;
  console.log(this.b);
  console.log(b); 
})();
// 立即执行函数是在全局作用域中直接调用的,而不是作为对象的方法调用。在非严格模式下,默认情况下,函数中的this指向全局对象window。即this.b = 10
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 13.下面代码输出什么

var a = 10;
(function () {
  console.log('-', a)
  a = 5
  console.log('-', window.a)
  var a = 20;
  console.log('-', a)
})()

// 输出结果:
// - undefined
// - 10
// - 20

// 解析执行步骤
var a = undefined
a = 10;
(function () {
  // 变量提升(预解析)
  var a = undefined
  console.log('-', a)  // - undefined
  a = 5
  console.log('-', window.a)  // 找window(全局)对象的a, 输出10
  a = 20;
  console.log('-', a) // - 20
})()
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

# 14.给某个资源链接,如https://www.baidu.com/index.html,请实现一个方法,获取该资源的后缀,如html

const getSuffixStr = () => {
  if(typeof str !== 'string') {
      return ''
  }

  // 方法一:
  return str.slice(str.lastIndexOf('.') + 1)
  // return str.substring(str.lastIndexOf('.') + 1)

  // 方法二:
  return str.split('.').pop().toLowerCase()
}
1
2
3
4
5
6
7
8
9
10
11
12

# 15.介绍下 Set、Map的区别

Set和Map的只要场景在于数据重组和数据存储
Set是一种叫做集合的数据结构,Map是一种叫做字典的数据结构

# Set(集合)

ES6新增的一种新的数据结构,类似于数组,但成员是唯一且无序的,没有重复的值
Set 本身是一种构造函数,用来生成 Set 数据结构

const s = new Set()
[1, 2, 3, 4, 3, 2, 1].forEach(x => s.add(x))

for (let i of s) {
  console.log(i)	// 1 2 3 4
}

// 去重数组的重复对象
let arr = [1, 2, 3, 2, 1, 1]
[... new Set(arr)]	// [1, 2, 3]
1
2
3
4
5
6
7
8
9
10

Set 对象允许你储存任何类型的唯一值,无论是原始值或者是对象引用。 向 Set 加入值的时候,不会发生类型转换,所以5和"5"是两个不同的值。Set 内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality”,它类似于精确相等运算符(===),主要的区别是NaN等于自身,而精确相等运算符认为NaN不等于自身。

Set 实例属性

  • constructor: 构造函数
  • size:元素数量
let set = new Set([1, 2, 3, 2, 1])

console.log(set.length)	// undefined
console.log(set.size)	// 3
1
2
3
4

Set 实例方法

  • add(value):新增,相当于 array里的push
  • delete(value):存在即删除集合中value
  • has(value):判断集合中是否存在 value
  • clear():清空集合
let set = new Set()
set.add(1).add(2).add(1)

set.has(1)	// true
set.has(3)	// false
set.delete(1)	
set.has(1)	// false
1
2
3
4
5
6
7

Array.from 方法可以将 Set 结构转为数组

const items = new Set([1, 2, 3, 2])
const array = Array.from(items)
console.log(array)	// [1, 2, 3]
// 或
const arr = [...items]
console.log(arr)	// [1, 2, 3]
1
2
3
4
5
6

遍历方法(遍历顺序为插入顺序)

  • keys():返回一个包含集合中所有键的迭代器
  • values():返回一个包含集合中所有值得迭代器
  • entries():返回一个包含Set对象中所有元素得键值对迭代器
  • forEach(callbackFn, thisArg):用于对集合成员执行callbackFn操作,如果提供了 thisArg 参数,回调中的this会是这个参数,没有返回值
let set = new Set([1, 2, 3])
console.log(set.keys())	// SetIterator {1, 2, 3}
console.log(set.values())	// SetIterator {1, 2, 3}
console.log(set.entries())	// SetIterator {1, 2, 3}

for (let item of set.keys()) {
  console.log(item);
}	// 1	2	 3
for (let item of set.entries()) {
  console.log(item);
}	// [1, 1]	[2, 2]	[3, 3]

set.forEach((value, key) => {
    console.log(key + ' : ' + value)
})	// 1 : 1	2 : 2	3 : 3
console.log([...set])	// [1, 2, 3]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

Set很容易实现交集(Intersect)、并集(Union)、差集(Difference)

let set1 = new Set([1, 2, 3])
let set2 = new Set([4, 3, 2])

let intersect = new Set([...set1].filter(value => set2.has(value)))
let union = new Set([...set1, ...set2])
let difference = new Set([...set1].filter(value => !set2.has(value)))

console.log(intersect)	// Set {2, 3}
console.log(union)		// Set {1, 2, 3, 4}
console.log(difference)	// Set {1}
1
2
3
4
5
6
7
8
9
10

# Map(字典)

Map 对象保存键值对,并且能够记住键的原始插入顺序。
集合与字典的区别:

  • 共同点:集合、字典 可以储存不重复的值
  • 不同点:集合 是以 [value, value]的形式储存元素,字典 是以 [key, value] 的形式储存
    属性:
  • constructor:构造函数
  • size:返回字典中所包含的元素个数
const map = new Map([
  ['name', 'An'],
  ['des', 'JS']
]);

map.size // 2
1
2
3
4
5
6

操作方法:

  • set(key, value):向字典中添加新元素
  • get(key):通过键查找特定的数值并返回
  • has(key):判断字典中是否存在键key
  • delete(key):通过键 key 从字典中移除对应的数据
  • clear():将这个字典中的所有元素删除 遍历方法:
  • Keys():将字典中包含的所有键名以迭代器形式返回
  • values():将字典中包含的所有数值以迭代器形式返回
  • entries():返回所有成员的迭代器
  • forEach():遍历字典的所有成员
const map = new Map([
      ['name', 'An'],
      ['des', 'JS']
  ]);
console.log(map.entries())	// MapIterator {"name" => "An", "des" => "JS"}
console.log(map.keys()) // MapIterator {"name", "des"}
1
2
3
4
5
6

与其他数据结构的相互转换

  • Map 转 Array
const map = new Map([[1, 1], [2, 2], [3, 3]])
console.log([...map])	// [[1, 1], [2, 2], [3, 3]]
1
2
  • Array 转 Map
const map = new Map([[1, 1], [2, 2], [3, 3]])
console.log(map)	// Map {1 => 1, 2 => 2, 3 => 3}
1
2

# 区别:

Set(集合):

  • Set是一种有序且唯一的值的集合,它的值可以是任何类型(原始值或对象引用)。
  • Set中的值是唯一的,重复的值会被忽略。
  • 可以通过迭代器访问Set中的值。
  • Set中的值没有特定的顺序,不保证插入顺序与访问顺序一致。
  • 主要用途:去重、判断值是否存在。
    Map(映射):
  • Map是一种键值对的集合,其中键和值可以是任何类型(原始值或对象引用)。
  • Map中的键是唯一的,每个键对应一个值。
  • 可以通过迭代器访问Map中的键值对。
  • Map保持插入顺序,即插入顺序与访问顺序一致。
  • 主要用途:存储关联数据、快速查找键对应的值。

# 类数组

类数组是指具有类似数组的特性,但并非真正的数组的对象。

  • 是对象,而不是数组实例。
  • 具有 length 属性,表示元素的数量。
  • 具有一系列以数字作为键的属性(索引),从0开始递增
    虽然类数组对象在语法上类似于数组,但它们通常没有数组对象上的方法和功能(如 push()、pop()、forEach() 等)
    使用场景:
  1. DOM 元素集合:document.getElementsByClassName() 或 document.querySelectorAll() 返回的就是类数组对象,可以通过索引访问和迭代这些元素。
  2. 函数的参数对象 arguments:它是函数内部的一个类数组对象,包含了传递给函数的所有参数,可以通过索引访问和遍历这些参数。
  3. 使用自定义的迭代器函数生成类数组对象。
    对于类数组对象,可以通过 Array.from() 方法将其转换为真正的数组,然后就可以使用数组的方法和功能。另外,也可以使用 Array.prototype 上的一些方法,如 call() 或 apply() 来操作类数组对象。

# 16.请输出结果

var a = {n: 1};
var b = a;
a.x = a = {n: 2};

console.log(a.x) 	// undefined
console.log(b.x)  // {n: 2}
1
2
3
4
5
6

考察点:

  1. 引用对象的变量存的是内存地址;(js中,对象的赋值是按引用传递的)
  2. 赋值顺序是从右向左
  3. (.)优先级[18]高于 (=赋值)的优先级[2]
    解析步骤:
  4. 第一步:
var a = {n: 1}  ==>

变量        堆内存地址    该地址指向的对象
a    -->    0x001    -->    {n: 1}
1
2
3
4
  1. 第二步:
var b = a
b    -->    0x001
// 这里b也指向了 0x001;而该值目前还是  {n: 1}
1
2
3
  1. 第三步:
a.x = a = {n: 2}
// 这里拆分出来写应该是这样的
// JS引擎在执行赋值语句时,会先从左往右解析各个变量名,转换成变量值,然后从右往左执行赋值 
1. [0x001].x = ....  // 这里 a要用内存地址0x001代表,因为它本身就是这个内存地址;....表示只声明还没赋值;所以此时 0x001 指向的值应该是 {n: 1,x: undefined}
2. a = {n: 2}  // 这里 a重新赋值了并且又是一个内存地址 0x002 ; 所以这里a又指向了 0x002
// a     -->    0x002    -->    {n: 2}
3. [0x001].x = {n: 2}  // 所以现在0x001 这个内存地址中值应该是{n: 1, x: {n: 2}} 
// 0x002 存储的值是 {n: 2}
1
2
3
4
5
6
7
8

最后:

a  -->    0x002    -->    {n: 2}
b    -->    0x001    -->    {n: 1, x: {n: 2}}
1
2

# 17.下面代码输出什么

const num = parseInt('7*6', 10)
1

只返回了字符串中第一个字母,设定了进制后(也就是第二个参数,指定需要解析的数字是什么进制:十进制、十六进制、八进制、二进制等等),parseInT检查字符串中的字符是否合法,一旦遇到一个在指定进制中不合法的字符后,立即停止解析并且忽略后面所有的字符。
*就是不合法的数字字符,所以只解析到'7',并将其解析为十进制的7

parseInt语法:

parseInt(string, radix);
// parseInt函数将其第一个参数转换为一个字符串,对该字符串进行解析,然后返回一个整数或 NaN
// 如果第一个字符不能转换为数字,parseInt 会返回 NaN
1
2
3

参数:

  • string 要被解析的值。如果参数不是一个字符串,则将其转换为字符串 (使用 ToString抽象操作)。字符串开头的空白符将会被忽略。
  • radix 从 2 到 36 的整数,表示进制的基数。例如指定 16 表示被解析值是十六进制数。如果超出这个范围,将返回 NaN。假如指定 0 或未指定,基数将会根据字符串的值进行推算。注意,推算的结果不会永远是默认值 10!文章后面的描述解释了当参数 radix 不传时该函数的具体行为。 返回值
    从给定的字符串中解析出的一个整数
    或者NaN,当
  • radix小于2或大于 36,或
  • 第一个非空格字符不能转换为数字

# 18.实现一个函数,对一个url进行请求,失败就再次请求,超过最大次数就走失败回调,任何一次成功都走成功回调

// url:请求接口地址
// body:设置的请求体
// succ:请求成功后的回调
// error:请求失败后的回调
// maxCount:设置请求的数量
function request(url, body, succ, error, maxCount = 5) {
  return fetch(url, body)
    .then(res => succ(res))
    .catch(err => {
      if(maxCount <= 0) return error('请求超时')
      return request(url, body, succ, error, --maxCount)
    })
}
// 调用请求函数
request('https://java.some.com/pc/reqCount', { method: 'GET', headers: {} },
  (res) => {
      console.log(res.data);
  },
  (err) => {
      console.log(err);
  })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 19.描述下列代码的执行结果

class Foo {
    constructor(arr) { 
        this.arr = arr; 
    }
    bar(n) {
        return this.arr.slice(0, n);
    }
}
var f = new Foo([0, 1, 2, 3]);
console.log(f.bar(1));
console.log(f.bar(2).splice(1, 1));
console.log(f.arr);
// [ 0 ]
// [ 1 ]
// [ 0, 1, 2, 3 ]
// slice不会改变原数组。f.bar(1)即arr.slice(0, 1):提取从索引0-1的数组元素
// f.bar(2)即arr.slice(0, 2):提取从索引0-2的数组元素,此时返回值[0, 1]。然后[0, 1].splice(1, 1),截取索引1开始之后的1个元素,即[1]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 20.实现5.add(3).sub(2)

// 可以考虑在 Number 类型的原型上添加 add 和 sub 方法,这两个方法返回新的数
Number.prototype.add = function (number) {
  if (typeof number !== 'number') {
    throw new Error('请输入数字~');
  }
  return this.valueOf() + number;
};
Number.prototype.minus = function (number) {
  if (typeof number !== 'number') {
    throw new Error('请输入数字~');
  }
  return this.valueOf() - number;
};
console.log((5).add(3).minus(2)); // 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 21.给定两个数组,求交集

  • 输出结果中的每个元素一定是唯一的
  • 我们可以不考虑输出结果的顺序
// 方法一:
// 注意:这种解法,时间复杂度为O(n^2),其中n是数组的长度。另外一个问题是交集的结果中可能包含重复的元素
const a = [0, 3, 2, 3]
const b = [0, 1, 3, 3]
const find = (a, b) => {
  return a.filter((item) => b.some((val) => val === item))
};
find(a, b)  // [0, 3, 3]

// 方法二:
// 避免重复的问题可以使用set来解决
function intersection(arr1, arr2) {
  const set1 = new Set(arr1);
  const set2 = new Set(arr2);
  const result = [];

  for (const num of set1) {
    if (set2.has(num)) {
      result.push(num);
    }
  }
  return result;
}

const array1 = [1, 2, 3, 4, 5];
const array2 = [4, 5, 6, 7, 8];
const result = intersection(array1, array2);
console.log(result);  // 输出: [4, 5]
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

# 22.javascript中什么是伪数组?如何将伪数组转换为标准数组

在JavaScript中,伪数组是指具有类似数据结构的对象,但并不是正真的数组。他们有一下特点:

  1. 类数组对象:伪数组具有类似数组的结构,拥有length属性和通过索引访问元素的能力
  2. 非数组方法:伪数组通常不具备数组对象上的方法,如:push()、pop()、forEach()
  3. 原型链:伪数组一般不继承自Array.prototype,而是继承自Object.prototype
    常见的伪数组包括函数的arguments对象,DOM对象集合(例如document.getElementsByTagName()返回的结果)以及其他具有类似结构的对象。
    要将伪数组转换为标准数组,可以使用一些方法:
  4. Array.from():可以使用Array.from()方法将伪数组转换为标准数组。这个方法接受一个可迭代对象或伪数组,并返回一个新的数组。
const arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 };
const array = Array.from(arrayLike);
console.log(array);  // 输出: ['a', 'b', 'c']
1
2
3
  1. Array.prototype.slice.call():可以通过将Array.prototype.slice方法与Function.prototype.call方法结合使用来将伪数组转换为标准数组
const arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 };
const array = Array.prototype.slice.call(arrayLike);
console.log(array);  // 输出: ['a', 'b', 'c']
1
2
3
  1. Spread Operator(展开运算符):使用展开运算符...可以将伪数组转换为标准数组
const arrayLike = { 0: 'a', 1: 'b', 2: 'c', length: 3 };
const array = [...arrayLike];
console.log(array);  // 输出: ['a', 'b', 'c']
1
2
3
最近更新时间: 6/5/2023, 10:28:56 AM
강남역 4번 출구
Plastic / Fallin` Dild