8 个有趣的 JavaScript 题目

发布于 2022-09-21 13:00:08 字数 3421 浏览 120 评论 0

1、sort

const arr1 = ['a', 'b', 'c'];
const arr2 = ['b', 'c', 'a'];

console.log(
  arr1.sort() === arr1,
  arr2.sort() == arr2,
  arr1.sort() === arr2.sort()
);
Answer: true, true, false

首先,array sort 方法对原始数组进行排序,并返回对该数组的引用。这意味着在编写arr2.sort() 时,arr2 数组对象将被排序。

然而,在比较对象时,数组的排序顺序并不重要。因为 arr1.sort()arr1 指向内存中的同一个对象,所以第一个相等比较时返回 true。对于第二个比较也是这样:arr2.sort()arr2 指向内存中的同一个对象。

在第三个比较中,arr1.sort()arr2.sort() 的排序顺序相同;但是,它们指向内存中的不同对象。因此,第三个测试结果为 false

2、Set 对象

const mySet = new Set([{ a: 1 }, { a: 1 }]);
const result = [...mySet];
console.log(result);
Answer: [{a: 1}, {a: 1}]

虽然 Set 对象确实会删除重复项,但我们使用的两个值是对内存中不同对象的引用,尽管它们具有相同的键值对。这与 {a:1}=={a:1}false 的原因相同。

应该注意的是,如果集合是使用对象变量(比如 obj={a:1} )创建的,那么新集合([obj,obj])将只有一个元素,因为数组中的两个元素引用内存中的同一个对象。

3、Object.freeze

const user = {
  name: 'Joe',
  age: 25,
  pet: {
    type: 'dog',
    name: 'Buttercup'
  }
};

Object.freeze(user);
user.pet.name = 'Daffodil';
console.log(user.pet.name);
Answer: Daffodil

Object.freeze 对象冻结将对对象执行浅冻结,但不会保护深层属性修改不受影响。在这个例子中,我们无法修改 user.age,但我们可以修改 user.pet.name. 如果我们觉得需要保护对象不被“修改,我们可以递归地使用对象冻结或者使用现有的“深度冻结”库。

4、Prototype

function Dog(name) {
  this.name = name;
  this.speak = function() {
    return 'woof';
  };
}

const dog = new Dog('Pogo');

Dog.prototype.speak = function() {
  return 'arf';
};

console.log(dog.speak());
Answer: woof

每次创建一个新的 Dog 实例时,我们都将该实例的 speak 属性设置为返回字符串 woof 的函数。因为每次我们创建一个新的 Dog 实例时都会设置这个属性,所以解释器永远不必在原型链上查找更远的内容来找到 speak 属性。

5、Promise.all

const timer = a => {
  return new Promise(res =>
    setTimeout(() => {
      res(a);
    }, Math.random() * 100)
  );
};

const all = Promise.all([
  timer('first'),
  timer('second')
]).then(data => console.log(data));
Answer: ["first", "second"]

我们可以可靠地以数组参数中提供它们的相同顺序返回。

6、Reduce

const arr = [
  x => x * 1,
  x => x * 2,
  x => x * 3,
  x => x * 4
];

console.log(arr.reduce((agg, el) => agg + el(agg), 1));
Answer: 120

对于Array#reduce,聚合的初始值(这里称为 agg )在第二个参数中给出。在这种情况下,是1。然后,我们可以对函数进行迭代,如下所示:

1 + 1 * 1 = 2 
2 + 2 * 2 = 6
6 + 6 * 3 = 24
24 + 24 * 4 = 120

7、扩展运算符

const arr1 = [{ firstName: 'James' }];
const arr2 = [...arr1];
arr2[0].firstName = 'Jonah';

console.log(arr1);
Answer: [{ firstName: "Jonah" }]

扩展运算符创建数组的浅拷贝,这意味着 arr2 中包含的对象仍指向 arr1 对象所指向的内存中的同一对象。因此,更改一个数组中对象的 firstName 属性也会被另一个数组中的对象所反映。

8、Array

const map = ['a', 'b', 'c'].map.bind([1, 2, 3]);
map(el => console.log(el));
Answer: 1 2 3

['a','b','c'].map调用时,this 指向的是['a', 'b', 'c'],当通过 bind 方法修改 this 之后指向时变成了[1, 2, 3],所以代码可以改写成这种方式:

[1, 2, 3].map(el => console.log(el))

好了,今天的文章分享到这里,欢迎大家点赞留言和收藏。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

安穩

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

束缚m

文章 0 评论 0

alipaysp_VP2a8Q4rgx

文章 0 评论 0

α

文章 0 评论 0

一口甜

文章 0 评论 0

厌味

文章 0 评论 0

转身泪倾城

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文