8个JavaScript题目

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))

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章