面试题3(day1)
Opened this issue · 0 comments
robbiemie commented
手写继承
原型继承
function Parent() {}
Parent.prototype.a = 1;
function Child() {}
Child.prototype = Parent.prototye
Child.prototype.constructor = Child
寄生组合继承
// 超类型构造函数
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function() {
console.log(this.name);
};
// 辅助函数,实现继承
function inheritPrototype(subType, superType) {
var prototype = Object.create(superType.prototype); // 创建对象,创建父类原型的一个副本
prototype.constructor = subType; // 增强对象,弥补因重写原型而失去的默认的 constructor 属性
subType.prototype = prototype; // 指定对象,将新创建的对象赋值给子类型的原型
}
// 子类型构造函数
function SubType(name, age) {
SuperType.call(this, name); // 第一次调用 SuperType()
this.age = age;
}
// 寄生组合式继承
inheritPrototype(SubType, SuperType);
// 新的子类型原型方法
SubType.prototype.sayAge = function() {
console.log(this.age);
};
// 测试寄生组合式继承
var instance = new SubType("Nicholas", 29);
instance.colors.push("black");
console.log(instance.colors); // "red,blue,green,black"
instance.sayName(); // "Nicholas"
instance.sayAge(); // 29
2. instanceof 实现原理
用于检测构造函数的 prototype 属性是否出现在实例对象的原型链上
function instanceOf (ins,cons) {
if(!ins) return false
if(ins.__proto__ === cons.prototype) {
return true
} else {
// 原型链继承,子类的原型对象指向父级的原型对象
ins = ins.__proto__
return instanceOf(ins, cons)
}
}
function Child () {}
let c = new Child()
3. promise 限制并发数
const URLS = [
'A.COM',
'B.COM',
'C.COM',
'D.COM',
'E.COM',
'F.COM',
'G.COM',
]
const resolveUrlFn = url => {
return new Promise(resolve => {
setTimeout(()=> {
resolve(`当前: ${url} 任务,执行完成`)
}, 1000)
}).then(res => {
console.log('异步回调', res)
})
}
const pool = new PromisePool(3, resolveUrlFn)
pool.start(URLS)
方案1:
class PromisePool {
constructor(num, callback) {
this.limit = num;
this.urls = [];
this.pools = []
this.resolveFn = callback
}
start(urls) {
this.urls = urls
this.exec()
}
exec() {
while(this.urls.length) {
if(this.pools.length < this.limit) {
// 加入并发池
let url = this.urls.pop();
let task = this.resolveFn(url)
this.pools.push(task)
task.then(res => {
let index = this.pools.findIndex(item => task);
this.pools.splice(index, 1);
})
}
}
}
}
方案2:
class PromisePool {
constructor(num, callback) {
this.limit = num;
this.urls = [];
this.pools = []
this.resolveFn = callback
}
start(urls) {
this.urls = urls
while(this.pools.length < this.limit && this.urls.length) {
this.execTask()
}
const race = Promise.race(this.pools);
this.loop(race)
}
loop(race) {
race.then(() => {
this.execTask()
let race = Promise.race(this.pools);
this.loop(race)
})
}
execTask() {
let url = this.urls.pop();
let task = this.resolveFn(url);
this.pools.push(task);
task.then(res => {
let index = this.pools.findIndex(item => item === task)
this.pools.splice(index, 1);
})
}
}
6.https 实现原理
- 校验证书合法性(获取证书公钥)
- 用公钥加密,采用的对应加密算法和秘钥
- 通过对称加密,建立通信
参考文档
7. 节流与防抖
- 防抖(debounce)
作用是在短时间内多次触发同一个函数,只执行最后一次,或者只在开始时执行
应用场景: 点击事件
/**
* 创建一个防抖函数
* @param {Function} func 需要防抖的函数
* @param {number} wait 等待时间(毫秒)
* @param {boolean} immediate 是否立即执行
* @return {Function} 返回防抖处理后的函数
*/
function debounce(func, wait, immediate) {
let timeout;
return function() {
// 保存函数调用时的上下文和参数,传递给 func
const context = this;
const args = arguments;
// 如果定时器已存在,清除之前的定时器
clearTimeout(timeout);
// 立即执行,只有在 wait 时间内不再触发事件才再次设定定时器
if (immediate && !timeout) {
func.apply(context, args);
}
// 设定一个新的定时器,使事件在 wait 毫秒后执行
timeout = setTimeout(function() {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
}, wait);
};
}
- 节流(throttle)
节流是指在一段时间内只允许函数执行一次。
应用场景: scroll 事件
/**
* 创建一个节流函数
* @param {Function} func 需要节流的函数
* @param {number} wait 间隔时间(毫秒)
* @return {Function} 返回节流处理后的函数
*/
function throttle(func, wait) {
let inThrottle, lastFunc, lastRan;
return function() {
const context = this;
const args = arguments;
if (!inThrottle) {
func.apply(context, args);
lastRan = Date.now();
inThrottle = true;
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(function() {
if (Date.now() - lastRan >= wait) {
func.apply(context, args);
lastRan = Date.now();
}
}, Math.max(wait - (Date.now() - lastRan), 0));
}
};
}