持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情
目录
今日题
题目
实现一个类 名称:CallbackSavior
属性:自定义
方法:push
,run
使用:
const cbs = new CallbackSavior();
// 向实例对象中存储一个回调函数,形参初始值为null
cbs.push(value => {
console.log(value); // null
return value ?? 1; // 返回给下一个可执行函数
})
// 添加一个新的回调函数,函数的第一个形参为上一个回调函数的返回值
cbs.push(value => {
console.log(value); // 1
return ++value;
})
// 添加一个基本数据类型,该值会直接成为下一个回调函数的形参
cbs.push("aaa");
cbs.push(value => {
console.log(value); // aaa
return "bbb";
})
// 添加一个Promise数据,await关键字获取到的值将成为下一个可执行函数的参数
cbs.push(new Promise(res => res("ccc")))
cbs.push(value => {
console.log(value); // ccc
return "ddd";
})
// run为异步函数,作用是运行存储起来的数据,返回一个Promise,成功状态下(then方法的第一个回调函数)的参数为最后一个可执行函数的返回值
cbs.run().then(value => {
console.log(value); // ddd
});
分析
本题涵盖知识点:类,实例对象,Promise,回调函数,async(异步函数的实现)……
push
方法可向实例对象中存储所有类型的数据,传进来的数据会被当作下一个可执行函数的第一个形参,除了Function和Promise类型的数据,这两种数据类型会获取返回值作为下一个可执行函数的形参
run
方法按照从前往后的顺序依次获取实例对象中存储的数据作为下一个可执行函数的参数,如果遇到Function和Promise则获取其返回值作为下一个可执行函数的参数,还有!当run
函数执行结束后,实例对象中存储数据的地方应被清空
注意:run
是一个异步函数,目的是为了可以正常获取Promise数据类型的值
昨日题
题目
写出以下函数的执行结果,输出以单个空格分隔
function Fun() {
say = function() {
console.log(1)
}
return this
}
Fun.say = function () {
console.log(2)
}
function say() {
console.log(3)
}
var say = function() {
console.log(4)
}
Fun.prototype.say = function () {
console.log(5)
}
Fun.say()
say()
Fun().say()
new Fun.say()
new Fun().say()
say()
答案
2 4 1 2 5 1
解析
在解析答案之前我们先来看一下上面代码JS声明提升后的样子
function Fun() {
say = function() {
console.log(1)
}
return this // window
}
function say() {
console.log(3)
}
var say;
Fun.say = function () {
console.log(2)
}
say = function() {
console.log(4)
}
Fun.prototype.say = function () {
console.log(5)
}
第一个Fun.say()
:使用Fun
对象下面的say()
方法
Fun.say = function () {
console.log(2)
}
第二个say()
:使用say()
函数,在JS变量提升后的代码我们可以看到是先声明function say() {}
函数,但是后面同名称的变量say
被赋予了新的值function() { console.log(4) }
,所以在结尾调用该方法的时候调用的是变量say
var say = function() {
console.log(4)
}
第三个Fun().say()
:使用Fun()
函数返回的对象中的say()
方法,在Fun()
函数中又重新对最近的say
名称变量进行了重新赋值,还有Fun()
函数是用function
关键字声明的,所以this
指向它的调用者,也就是全局对象window
,进而这部分可演化为修改全局变量say
为function() { console.log(1) }
后使用say
变量
function Fun() {
say = function() {
console.log(1)
}
return this
}
第四个new Fun.say()
:执行了一次Fun
对象下面的say()
方法,并返回对应的实例对象,但是该方法中没有对this
做出什么修改,所以返回了一个空的实例对象
Fun.say = function () {
console.log(2)
}
第五个new Fun().say()
:对Fun()
函数执行了一次new
的操作,在返回的实例对象中又调用了say
方法,在返回的实例对象中并没有say
方法,因为this
上没有绑定say
方法,所以到它的构造函数Fun()
下面的prototype
对象上面去找,最后找到了function () { console.log(5) }
;
Fun.prototype.say = function () {
console.log(5)
}
最后一个say()
:因为最后跟say
有接触的是Fun()
方法里面,所以调用的是修改的后的函数
say = function() {
console.log(1)
}
结语
此文章已收录至《JavaScript每日一题》专栏,如果你对本专栏有任何建议,欢迎反馈。如果你对此文章中的题目还有不懂的地方,那么请在评论区留言与大家一起讨论吧。 创作不易,少年,就请留个赞再走吧!