专栏声明:只求用最简单的,容易理解的方法通过,不求优化,不喜勿喷
2618. 检查是否是类的对象实例
题面
请你编写一个函数,检查给定的对象是否是给定类或超类的实例。
可以传递给函数的数据类型没有限制。
知识点:
原型链
思路
通过 JavaScript 的元素的 constructor 属性可以判断它是不是某个类创建的,同时因为有继承关系,我们可以通过 Object.getPrototypeOf 可以拿到对象原型链的上一级,我们一层一层向上寻找,直到没有上一级为止。
要注意一点:null和undefined 不是对象构建的,所以不能用这个判断,但是本题目是检查类的对象实例,所以如果给定的是 undefined 或者 null ,他们肯定不是类的实例对象,所以返回 false 即可
代码
var checkIfInstanceOf = function(obj, classFunction) {
if(obj === undefined || obj === null) return false;
while(obj!==null) {
if(obj.constructor === classFunction) return true;
obj = Object.getPrototypeOf(obj);
}
return false;
};
/**
* checkIfInstanceOf(new Date(), Date); // true
*/
2619. 数组原型对象的最后一个元素
题面
请你编写一段代码实现一个数组方法,使任何数组都可以调用 array.last() 方法,这个方法将返回数组最后一个元素。如果数组中没有元素,则返回 -1 。
知识点:
数组
思路
在数组对象上挂在一个函数,this 可以拿到这个对象(实例化之后拿到的是那个实例),返回它的最后一位即可,如果没有元素返回 -1
代码
Array.prototype.last = function () {
return this.length > 0 ? this[this.length - 1] : -1;
};
/**
* const arr = [1, 2, 3];
* arr.last(); // 3
*/
2620. 计数器
题面
请你编写并返回一个 计数器 函数,它接收一个整型参数 n 。这个 计数器 函数最初返回 n,每次调用它时返回前一个值加 1 的值 ( n , n + 1 , n + 2 ,等等)。
知识点:
闭包
思路
闭包的概念题,先简单说一下概念:
- 在 js 中,一个函数可以获取其外部的变量(父级或者以上作用域),但是函数外部不能访问函数内部的变量,我们通过返回一个函数,可以获取一个函数的内部的变量,因为返回的这个函数可以访问其外部函数的内部变量,只要函数返回这个变量我们就可以获得它。我们定义:如果一个函数访问了此函数的父级及父级以上的作用域变量,那么这个函数就是一个闭包。
- 闭包能形成的原因是, js 中,当一个对象被其他对象引用,那么它在会一直在内存中,不会回收,所以如果我们的函数访问了一个变量,那么它就会一直在内存中存在,所以我们可以一直获得和操作它。
那么这题的逻辑就很简单了:它初始化了一个初始值,我们把这个初始值存在 createCounter 的一个内部变量中,之后返回一个操作函数,这个操作函数访问了内部变量,并且每次让他 + 1,那么每次我们调用它的时候,就可以实现计数器了。
代码
var createCounter = function(n) {
let cnt = n;
return function() {
return cnt++;
};
};
/**
* const counter = createCounter(10)
* counter() // 10
* counter() // 11
* counter() // 12
*/
2621. 睡眠函数
题面
请你编写一个异步函数,它接收一个正整数参数 millis ,并休眠这么多毫秒。要求此函数可以解析任何值。
知识点:
Promise、setTimeout
思路
使用 setTimeout 函数在指定时间后返回一个 Promise 即可
代码
async function sleep(millis) {
return new Promise(r => setTimeout(r,millis))
}
/**
* let t = Date.now()
* sleep(100).then(() => console.log(Date.now() - t)) // 100
*/
2622. 有时间限制的缓存
题面
编写一个类,它允许获取和设置键-值对,并且每个键都有一个 过期时间 。
该类有三个公共方法:
set(key, value, duration) :接收参数为整型键 key 、整型值 value 和以毫秒为单位的持续时间 duration 。一旦 duration 到期后,这个键就无法访问。如果相同的未过期键已经存在,该方法将返回 true ,否则返回 false 。如果该键已经存在,则它的值和持续时间都应该被覆盖。
get(key) :如果存在一个未过期的键,它应该返回这个键相关的值。否则返回 -1 。
count() :返回未过期键的总数。
知识点:
setTimeout、Map
思路
为每次存储的键值对存储开启一个计时器,规定时间后删除对应的键值,并且把这个计时器保存下来。
如果重新设置了这个键值,则清除之前的计时器,开始一个新的计时器。
因为计时器为为我们清理过期的键值,对于另外两个操作,我们只需要判断访问的键值是不是存在和返回 map 的即可。
代码
var TimeLimitedCache = function() {
this.map = new Map();
};
TimeLimitedCache.prototype.set = function(key, value, duration) {
let existed = this.map.has(key);
if (existed) {
let obj = this.map.get(key);
clearTimeout(obj.timer);
}
let timer = setTimeout(() => {
this.map.delete(key);
}, duration);
this.map.set(key, {
timer: timer,
value: value,
});
return existed;
};
TimeLimitedCache.prototype.get = function(key) {
let existed = this.map.has(key);
if (existed) {
let obj = this.map.get(key);
return obj.value;
}
return -1;
};
TimeLimitedCache.prototype.count = function() {
return this.map.size;
};
/**
* Your TimeLimitedCache object will be instantiated and called as such:
* var obj = new TimeLimitedCache()
* obj.set(1, 42, 1000); // false
* obj.get(1) // 42
* obj.count() // 1
*/