面试题
- 下面的输出结果是多少
const promise = new Promise((resolve, reject) => {
console.log(1);
resolve();
console.log(2);
})
promise.then(() => {
console.log(3);
})
console.log(4);
// 1 2 4 3
- 下面Set结构,打印出的size值是多少
let s = new Set();
s.add([1]);
s.add([1]);
console.log(s.size); //获取该set集合中的元素数量 2
- 下面的代码输出结果是
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 1000)
})
const promise2 = promise1.then(() => {
throw new Error('error!!!')
})
console.log('promise1', promise1) // pending
console.log('promise2', promise2) // pending
setTimeout(() => {
console.log('promise1', promise1) // resolved
console.log('promise2', promise2) // rejected
}, 2000)
- 下面代码的运行结果是
const promise = new Promise((resolve, reject) => {
resolve('success1')
reject('error'); //无效
resolve('success2'); //无效
})
promise
.then((res) => {
console.log('then: ', res) // then: success1
})
.catch((err) => {
console.log('catch: ', err)
})
- 下面的代码输出结果是多少
Promise.resolve(2)
.then((res) => {
console.log(res) // 2
return 2
})
.catch((err) => {
return 3
})
.then((res) => {
console.log(res) // 2
})
- 下面的代码输出结果是多少
Promise.resolve()
.then(() => {
return new Error('error!!!')
})
.then((res) => {
console.log('then: ', res) // then: Error: error!!!
})
.catch((err) => {
console.log('catch: ', err)
})
- 下面的代码输出结果是多少
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log) // 1
const myPromise = () =>
Promise.resolve('I have resolved')
const firstFunc = () => {
myPromise().then((res) => {
console.log(res + ' first');
});
console.log('first');
}
async function secondFunc() {
console.log(await myPromise());
console.log('second');
}
firstFunc(); // first , I have resolved first
secondFunc(); // I have resolved , second
(function() {
console.log(age); // undefined
console.log(name); //Uncaught ReferenceError: Cannot access 'name' before initialization 未捕获的引用错误:无法在初始化之前访问“name”
let name = 'PapaerCrane';
var age = 24;
})();
new Promise(resolve=>{
resolve(a)
}).then(result=>{
console.log(`成功:${result}`)
return result*10
},reason=>{
console.log(`失败:${reason}`)
}).then(result=>{
console.log(`成功:${result}`)
},reason=>{
console.log(`失败:${reason}`)
})
// 结果: 失败:ReferenceError: a is not defined 成功:undefined
// 分析: 因为a未定义,所以报错,执行了then方法里的错误回调,接着又返回一个promise,这个promise没有错误,调用了then方法里面的成功回调
补充扩展
1. Math.pow
—— ES2015
//Math.pow(底数,几次方)
console.log(Math.pow(2, 3)); // 8
console.log(2 ** 3); // 8
console.log(2 * 2 * 2); // 8
2. Object.entries Object.values
—— ES2015
Object.entries()
返回给定对象自身可枚举属性的 [key, value] 数组;可参考MDN
var obj = {
a:1,
b:2
}
Object.keys(obj) // ["a", "b"]
Object.values(obj) // [1, 2]
Object.entries(obj) // [["a", 1], ["b", 2]]
const object1 = {
a: 'somestring',
b: 42
};
for (let [key, value] of Object.entries(object1)) {
console.log(`${key}: ${value}`);
}
// "a: somestring"
// "b: 42"
const obj = {
a: 1,
b: 2,
c: "asdf",
d: "asfsfda",
e: true
};
//去掉数字属性,返回新的对象
const result = Object.entries(obj)
.filter(([key, value]) => typeof value !== "number")
.reduce((a, [key, value]) => {
a[key] = value;
return a;
}, {});
console.log(result); // { c: 'asdf', d: 'asfsfda', e: true }
3. ES2019新增数组API
Array.prototype.flat
该函数可以将某个数组拍扁 ; 可参考MDN
const arr = [1, [2, 3, [4, 5, [6, 7]]]];
const arr1 = arr.flat(); // [1, 2, 3, [4, 5, [6, 7]]]
const arr2 = arr.flat(2); // [1, 2, 3, 4, 5, [6, 7]]
const arr3 = arr.flat(Infinity); // [1, 2, 3, 4, 5, 6, 7]
Array.prototype.flatMap
flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。它与 map 连着深度值为1的 flat 几乎相同,但 flatMap 通常在合并成一种方法的效率稍微高一些。
可参考MDN
const arr = ...;
arr.flatMap(fn);
//等效于
arr.map(fn).flat()
const arr = [1, 3, [2, 3, [4, 5, [6, 7]]]];
// const newArr = arr.map(n => (typeof n === "number" ? n * 20 : n)).flat();
const newArr = arr.flatMap(n => (typeof n === "number" ? n * 20 : n));
console.log(newArr); // [ 20, 60, 2, 3, [ 4, 5, [ 6, 7 ] ] ]
示例1:利用flatMap在map期间去掉一些数据
const arr = [1, 2, 3, 4, 5];
// const newArr = arr
// .filter(n => n % 2 !== 0)
// .map(n => ({ number: n, doubleNumber: n * 2 }));
// [{number:1, doubleNumber:2}, [], {...}, [], {...}];
const newArr = arr.flatMap(n =>
n % 2 === 0 ? [] : { number: n, doubleNumber: n * 2 }
);
console.log(newArr);
/*
[
{number:1, doubleNumber: 2},
{number:3, doubleNumber: 6},
{number:5, doubleNumber: 10},
]
*/
示例2:利用flatMap分割一个单词数组
const arr = [
"Yestoday is a History",
"Tomorrow is a Mystery",
"Today is a Gift",
"That's why we call it thePresen"
];
/*
["Yestoday", "is", "a", "History", "Tomorrow", ...]
*/
// [["..", "...", ".."], ["...", "..."]]
const newArr = arr.flatMap(str => str.split(" "));
console.log(newArr);
Object.fromEntries
方法把键值对列表转换为一个对象
可参考MDN
Object.fromEntries(iterable)
它接收一个可迭代对象,该对象每次迭代必须返回一个包含两项数据的数组(参考map),该函数会将第一项作为对象的属性名,第二项作为对象的属性值
const arr = [["a", 1], ["b", 2]]
Object.fromEntries(arr); // {a:1, b:2}
示例:
function localMoneyFomat(obj) {
const entries = Object.entries(obj).map(([key, value]) =>
typeof value === "number" ? [key, "¥" + value] : [key, value]
);
return Object.fromEntries(entries)
}
var obj = {
name: "xxx",
balance: 199.8, //余额
taken: 3000 //消费
};
const newObj = localMoneyFomat(obj);
console.log(newObj); // { name: 'xxx', balance: '¥199.8', taken: '¥3000' }