检查是否是类的对象实例
请你编写一个函数,检查给定的值是否是给定类或超类的实例。
可以传递给函数的数据类型没有限制。例如,值或类可能是 undefined 。
示例 1:
输入:func = () => checkIfInstance(new Date(), Date)
输出:true
解释:根据定义,Date 构造函数返回的对象是 Date 的一个实例。示例 2:
输入:func = () => { class Animal {}; class Dog extends Animal {}; return checkIfInstance(new Dog(), Animal); }
输出:true
解释:
class Animal {};
class Dog extends Animal {};
checkIfInstanceOf(new Dog(), Animal); // true
Dog 是 Animal 的子类。因此,Dog 对象同时是 Dog 和 Animal 的实例。示例 3:
输入:func = () => checkIfInstance(Date, Date)
输出:false
解释:日期的构造函数在逻辑上不能是其自身的实例。示例 4:
输入:func = () => checkIfInstance(5, Number)
输出:true
解释:5 是一个 Number。注意,“instanceof” 关键字将返回 false。
思想:实例对象的__proto__
指向该实例对象的原型对象的prototype
对象,所以判断给定值是否是给定类的实例对象,直接判断obj.__proto__ === classFunction.prototype
即可,由于原型链的存在,所以还需判断obj.__proto__
的__proto__
是否指向原型对象的prototype
对象
prototype对象:用于放某同一类型实例的共享属性和方法,实质上是为了内存着想
每个实例对象都有一个__proto__
属性,指向构造函数的prototype
对象
var checkIfInstanceOf = function (obj, classFunction) {
if (
obj === null ||
obj === undefined ||
classFunction === null ||
classFunction === undefined
)
return false;
return (
obj.__proto__ === classFunction.prototype ||
checkIfInstanceOf(obj.__proto__, classFunction)
);
};
数组原型对象的最后一个元素
请你编写一段代码实现一个数组方法,使任何数组都可以调用array.last()
方法,这个方法将返回数组最后一个元素。如果数组中没有元素,则返回 -1 。
你可以假设数组是 JSON.parse
的输出结果。
示例 1 :
输入:nums = [null, {}, 3]
输出:3
解释:调用 nums.last() 后返回最后一个元素: 3。
示例 2 :
输入:nums = []
输出:-1
解释:因为此数组没有元素,所以应该返回 -1。
方法一:将 Nullish 合并运算符与 Array.prototype.at()
方法结合使用
Nullish:空合并运算符(??)。如果不为 null 或 undefined,则返回左侧操作数,否则返回右侧操作数。
Array.prototype.at()
方法接受一个整数值,并返回该索引处的元素,允许使用正整数和负整数。负整数从数组末尾开始计数。
Array.prototype.last = function() {
return this.at(-1) ?? -1;
}
方法二:为最后一个属性定义一个 getter来增强数组原型,getter 函数将返回另一个函数,该函数返回数组的最后一个元素,如果数组为空,则返回 -1。
Object.defineProperty(Array.prototype, 'last', {
get: function() {
return () => this.length ? this[this.length - 1] : -1;
}
});
当你定义一个 getter 时,你实际上是把 last 当作一个属性而不是一个函数。因此,它是通过
array.last
而不是array.last()
访问的。如果您将数组的最后一个元素视为该数组的属性,而不是函数的结果
计数器
给定一个整型参数 n,请你编写并返回一个 counter 函数。这个 counter 函数最初返回 n,每次调用它时会返回前一个值加 1 的值 ( n , n + 1 , n + 2 ,等等)。
示例 1:
输入: n = 10 [“call”,“call”,“call”] 输出:[10,11,12] 解释: counter() = 10 //
第一次调用 counter(),返回 n。 counter() = 11 // 返回上次调用的值加 1。 counter() = 12 //
返回上次调用的值加 1。 示例 2:
输入: n = -2 [“call”,“call”,“call”,“call”,“call”] 输出:[-2,-1,0,1,2]
解释:counter() 最初返回 -2。然后在每个后续调用后增加 1。
var createCounter = function(n) {
return function() {
return n++;
};
};
睡眠函数
请你编写一个异步函数,它接收一个正整数参数 millis ,并休眠 millis 毫秒。要求此函数可以解析任何值。
示例 1:
输入:millis = 100
输出:100
解释:
在 100ms 后此异步函数执行完时返回一个 Promise 对象
let t = Date.now();
sleep(100).then(() => {
console.log(Date.now() - t); // 100
});示例 2:
输入:millis = 200
输出:200
解释:在 200ms 后函数执行完时返回一个 Promise 对象
async function sleep(millis) {
return new Promise(resolve => {
setTimeout(resolve, millis);
});
}
扩展
async function example() {
try {
return new Promise((resolve, reject) => {
throw new Error('糟糕!');
});
} catch (err) {
console.error(err);
}
}
example(); // 错误不会被捕获,它拒绝了 example 返回的 promise。
async function example2() {
try {
return await new Promise((resolve, reject) => {
throw new Error('糟糕!');
});
} catch (err) {
console.error(err);
}
}
example2(); // 错误被捕获,example2 返回的 promise 被解决。
在 example 函数中,try 块不会捕获 promise 引发的错误,因为 promise 在引发错误之前就已经返回了。
在 example2 中,await 会导致函数等待 promise 完成或抛出错误,因此它可以捕获 promise 引发的错误。
有时间限制的缓存
编写一个类,它允许获取和设置键-值对,并且每个键都有一个 过期时间 。该类有三个公共方法:
- set(key, value, duration) :接收参数为整型键 key 、整型值 value 和以毫秒为单位的持续时间 duration 。一旦 duration 到期后,这个键就无法访问。如果相同的未过期键已经存在,该方法将返回 true ,否则返回 false 。如果该键已经存在,则它的值和持续时间都应该被覆盖。
- get(key) :如果存在一个未过期的键,它应该返回这个键相关的值。否则返回 -1 。
- count() :返回未过期键的总数。
示例 1:
输入: actions = [“TimeLimitedCache”, “set”, “get”, “count”, “get”]
values = [[], [1, 42, 100], [1], [], [1]] timeDeays = [0, 0, 50, 50, 150] 输出: [null, false, 42, 1, -1] 解释: 在 t=0 时,缓存被构造。 在 t=0 时,添加一个键值对(1: 42) ,过期时间为 100ms 。因为该值不存在,因此返回false。 在 t=50 时,请求 key=1 并返回值 42。 在t=50 时,调用 count() ,缓存中有一个未过期的键。 在 t=100 时,key=1 到期。 在 t=150 时,调用get(1) ,返回 -1,因为缓存是空的。
示例 2:
输入: actions = [“TimeLimitedCache”, “set”, “set”, “get”, “get”, “get”, “count”] values = [[], [1, 42, 50], [1, 50, 100], [1], [1], [1], []] timeDelays = [0, 0, 40, 50, 120, 200, 250] 输出: [null, false, true, 50, 50, -1] 解释: 在 t=0 时,缓存被构造。 在 t=0 时,添加一个键值对 (1: 42) ,过期时间为50ms。因为该值不存在,因此返回false。 当 t=40 时,添加一个键值对 (1: 50) ,过期时间为100ms。因为一个未过期的键已经存在,返回 true 并覆盖这个键的旧值。 在 t=50 时,调用 get(1) ,返回 50。 在t=120 时,调用 get(1) ,返回 50。 在 t=140 时,key=1 过期。 在 t=200 时,调用 get(1),但缓存为空,因此返回 -1。 在 t=250 时,count() 返回0 ,因为缓存是空的,没有未过期的键。