有些代码题前面打了问号?本人是有点不是很清楚,但结果都是一个一个在VScode上试过的,就是不知道怎么解析结果,欢迎大家在评论区评论!!!
目录
No.1
<script>
function sum(x) {
return function(y) {
return function(z) {
return x+y+z;
}
}
}
console.log(sum(1)(2)(3)); // 6
console.log(sum(1,2,3));
/* ƒ (y) {
return function(z) {
return x+y+z;
}
} */
</script>
答案:
6
test.html:21 ƒ (y) {
return function(z) {
return x+y+z;
}
}
No.2
[1,2,3].reduce((a,b) =>console.log(a,b))
答案:
解析:
reduce()接收一个函数作为累加器,需要函数return 数据,如果没有return,那么返回undefined给参数a
上述例子,第一个参数是a,第二个参数是b,在第一次调用时,累加器a为1,b为2,打印出来是 1和2;
第二次调用的时候,由于函数没有返回值,则就默认返回undefined。在下一次调用得到时候,累加器a为undefined,b为3,打印出来是 undefined和3
No.3
<script>
var a = 10;
(function a() {
a = 20; //这里的a是函数名,相当于修改函数a=20,无效
// 原因是普通函数可以修改变量名,立即执行函数不能修改变量名
console.log(a); // 函数调用
})();
console.log("a=",a);
</script>
答案:
解析:
首先存在变量提升和函数提升,所以一开始变量a被提升,值为undefined,由于函数提升优先级更高所以a先被赋值为函数。又因为是立即执行函数所以执行了函数a输出a目前的值(即函数),之后才是被赋值为10.
No.4
var twoSum = function(nums, target) {
let hash = {};
for(let i=0; i<nums.length; i++) {
// 如果在hash结构中找到值,那么就返回数组
if(hash[target - nums[i]] != undefined) {
return [hash[target - nums[i]] , i ];
}
hash[nums[i]] = i; // 键存的是数组值,值存的是数组元素下标。存入到hash结构中
}
};
No.5
process.nextTick(() => {
console.log('nextTick')
})
Promise.resolve()
.then(() => {
console.log('then')
})
setImmediate(() => {
console.log('setImmediate')
})
console.log('end')
// 答案:
end
nextTick
then
setImmediate
解析:
JS事件循环机制:
1、同步程序,Promise
2、process.nextTick
3、微任务,then
4、宏任务,计时器,ajax,读取文件
5、setImmediate
扩展:
作者:石墨文档
链接:https://juejin.cn/post/6844903509934997511
第一题
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
解析:该同步还是同步,即使同步里面有异步而且在前面,但是同步里面的同步输出还是在前面。reslove()调用then异步还是在后面输出
第二题
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 1000)
})
const promise2 = promise1.then(() => {
throw new Error('error!!!')
})
console.log('promise1', promise1)
console.log('promise2', promise2)
setTimeout(() => {
console.log('promise1', promise1)
console.log('promise2', promise2)
}, 2000)
答案:
解析:
promise是有3种状态:panding,fulfilled或rejected。
刚开始遇到的第一波console.log(),因为promise的返回结果放在定时器setTimeout中,所以需要等会在执行,因此第一波console.log()的输出为 “promise的状态为pending”,后来第二波console.log()输出的时候,是在定时器并且等2秒,那个时候前面的promise的状态已经全部转变好了,就可以正常输出。但上面的promise2并不是promise1,而是返回一个新的promise实例。(不知道这样解释对不对)
第三题
const promise = new Promise((resolve, reject) => {
resolve('success1')
reject('error')
resolve('success2')
})
promise
.then((res) => {
console.log('then: ', res)
})
.catch((err) => {
console.log('catch: ', err)
})
答案:
then: success1
解析:
构造函数中的resolve或reject只有一次执行有效,多次调用没有任何作用,因为promise状态一旦改变则不能再变。
第四题
Promise.resolve(1)
.then((res) => {
console.log(res)
return 2
})
.catch((err) => {
return 3
})
.then((res) => {
console.log(res)
})
答案:
1
2
解析:
?第五题
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('once')
resolve('success')
}, 1000)
})
const start = Date.now()
promise.then((res) => {
console.log(res, Date.now() - start)
})
promise.then((res) => {
console.log(res, Date.now() - start)
})
答案:
once
success 1006
success 1006
(这两个success后面的数字不固定)
解析:
promise.then或promise.catch可以调用多次,但这里Promise构造函数只执行一次。或者说promise内部状态一经改变,并且有了一个值,那么后续每次调用.then或者.catch都会直接拿到该值。
第六题
Promise.resolve()
.then(() => {
return new Error('error!!!')
})
.then((res) => {
console.log('then: ', res)
})
.catch((err) => {
console.log('catch: ', err)
})
答案:
then: Error: error!!!
解析:
.then
或 .catch
中return
一个error
对象并不会抛出错误,所以不会被后续的.catch
捕获。因为返回一个非promise
的值都会被包裹成promise
对象,即 return new Error('error!!!')
等价于 return Promise.resolve(new Error('error!!!'))
。
第七题
const promise = Promise.resolve()
.then(() => {
return promise
})
promise.catch(console.error)
答案:
出错:TypeError: Chaining cycle detected for promise #
解析:
.then
和.catch
返回的值不能是promise本身,否则会造成死循环
第八题
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
答案:
1
解析:
.then
或.catch
的参数应为函数,而传递非函数将导致值的结果被忽略,比如说.then(2)
这种就会被忽略,因为传递的是非函数,到了.then(console.log)
输出前面的Promise.resolve(1)
第九题
Promise.resolve()
.then(function success (res) {
throw new Error('error')
}, function fail1 (e) {
console.error('fail1: ', e)
})
.catch(function fail2 (e) {
console.error('fail2: ', e)
})
答案:
fail2: Error: error
解析:
Promise.resolve()
不出错,那么就是正确,执行.then(function sucess(res){ throw new Error('error')})
,抛出错误,被.catch()
捕获到,输出。
第十题
process.nextTick(() => {
console.log('nextTick')
})
Promise.resolve()
.then(() => {
console.log('then')
})
setImmediate(() => {
console.log('setImmediate')
})
console.log('end')
答案:
end
nextTick
then
setImmediate
No.6
<script>
let a = parseInt('2017-07-01')
let b = parseInt('2017abcdef')
let c = parseInt('abcdef2017')
console.log(a,b,c)
</script>
答案:2017 2017 NaN
No.7
<script>
let a = { a: 10 };
let b = { b: 10 };
let obj = {
a: 10
};
obj[b] = 20;
console.log(obj); // {a: 10, [object Object]: 20}
console.log(obj[b]); // 20
console.log(obj[a]); // 20
</script>
解析:
obj[b] = 20的赋值操作后,obj其实已经变成了{a:10,[object Object]:20},这是因为如果属性名表达式是一个对象的话,那么默认情况下会自动将对象转为字符串[object Object],最后一步获取obj[a]时,a本身也是一个对象,所以会被转换为获取obj[‘[object Object]’] 也就是上一步赋值的20
No.8
<script>
async function async1() {
console.log(1);
const result = await async2();
console.log(3);
}
async function async2() {
console.log(2);
}
Promise.resolve().then(() => {
console.log(4);
});
setTimeout(() => {
console.log(5);
});
async1();
console.log(6);
</script>
答案:
1
2
6
4
3
5
No.9
<script>
function arrayFromValue(item) {
return
[items];
}
console.log(arrayFromValue(10)); // undefined
</script>
解析:
如果在语句和数组文本表达式之间存在一个新行,JavaScript会自动在之前加;号,代码相当于如下:
return ;
[items];
}
所以返回的是undefined
No.10
<script>
const length = 4;
const numbers = [];
for (var i = 0; i < length; i); {
numbers.push(i 1);
}
console.log(numbers);
</script>
答案:
No.11
<script>
const clothes = ['jacket', 't-shirt'];
clothes.length = 0;
console.log(clothes[0]); // undefined
</script>
解析:数组长度改变的时候,数组的元素也会改变
No.12
<script>
function foo() {
let a = b = 0;
a;
return a;
}
foo();
console.log(typeof a); // undefined
console.log(typeof b); // number
</script>
解析:在代码第3行中等价于 let a = 0;b = 0;
b被声明为全局变量,a是函数内部的局部变量
? No.13
<script>
function Foo() {
getName = function () { alert(1); };
return this;
}
Foo.getName = function () { alert(2); };
Foo.prototype.getName = function () { alert(3); };
var getName = function () { alert(4); };
function getName() { alert(5); }
//请写出以下输出结果:
console.log(Foo.getName()); // 2
console.log(getName()); // 4
console.log(Foo().getName()); // 1
console.log(getName()); // 1
console.log(new Foo.getName()); // 2
console.log(new Foo().getName()); // 3
console.log(new new Foo().getName()); // 3
</script>
No.14
<style>
.box {
width: 400px;
border: solid 1px #000;
}
img {
width: 50%;
border-top: solid 1px red;
border-bottom: solid 1px blue;
}
</style>
<div class="box">
<img src="./1 (2).png" />
<img src="./1 (2).png" />
<img src="./1 (2).png" />
</div>
效果图:
解析:总div盒子宽度为 400px,而img图片宽度为50%(占总div盒子宽度的一半),那div盒子一行肯定是装不下,所以就掉下面,变成一列
No.15
async function a1 () {
console.log('a1 start')
await a2()
console.log('a1 end')
}
async function a2 () {
console.log('a2')
}
console.log('script start')
setTimeout(() => {
console.log('setTimeout')
}, 0)
Promise.resolve().then(() => {
console.log('promise1')
})
a1()
let promise2 = new Promise((resolve) => {
resolve('promise2.then')
console.log('promise2')
})
promise2.then((res) => {
console.log(res)
Promise.resolve().then(() => {
console.log('promise3')
})
})
console.log('script end')
答案:
script start
a1 start
a2
promise2
script end
promise1
a1 end
promise2.then
promise3
setTimeout
解析:首先是同步任务按顺序输出,再就是异步任务按顺序输出,定时器是最后输出,不管它的时间是多少,0也好,也都是最后输出
No.16
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
async function async2() {
console.log("async2");
}
console.log("script start");
setTimeout(function() {
console.log("setTimeout");
}, 0);
async1();
new Promise(function(resolve) {
console.log("promise1");
resolve();
}).then(function() {
console.log("promise2");
});
console.log("script end");
答案:
script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout
No.17
<script>
async function a() {
var result = Promise.resolve();
result.abort = function () {
console.log('xxx');
};
return result;
}
var p = a();
console.log(p.abort());
</script>
答案:
No.18
请写出inner的实际高度
<style>
.outer {
width: 200px;
height: 100px;
background-color: aqua;
}
.inner {
width: 60px;
height: 60px;
padding-top: 20%; /* outer宽度 * 20% = 40px */
background-color: blue;
}
</style>
<div class="outer">
<div class="inner"></div>
</div>
答案:100px
解析:因为inner元素的高度为 60px,再另外加上padding-top的40px就变成了100px
?No.19
var number = 10;
function fn() {
console.log(this);
console.log(this.number);
}
var obj = {
number: 2,
show: function (fn) {
this.number = 3;
fn();
arguments[0]();
}
};
obj.show(fn)
答案:
No.20
console.log(['1', '3', '10'].map(parseInt));
答案:[1, NaN, 2]
解析:
1、map的参数是
function(item, index, arr) { // 当前元素值,当前元素索引值,数组本身
}
2、parseInt的参数是
parseInt(item, index) // 解析的字符串,此时字符串是以⼏进制显示的(若省略或为0,则是10进制,若⼩于2或者⼤于36,则返回NaN)
3、['1', '3', '10'].map(parseInt) 代码其实是
const result = ['1', '3', '10'].map(function(cur, index, arr) {
return parseInt(cur, index);
});
// 执⾏过程:
// parseInt('1', 0) -> 1 把10进制的字符串1转为10进制(0代表十进制)则是1
// parseInt('3', 1) -> NaN 把1进制的字符串3转为10进制,没有1进制,则是NaN
// parseInt('10', 2) -> 2 把2进制的字符串10转为10进制,则是2