1、ES5的bind了解吗,有什么作用?能实现一下吗?
- 改变this指向
- 与call、apply不同,bind返回一个新函数
- 与call类似,参数只能一个一个传入,不能为数组
- bind类似函数柯里化
Function.prototype.myBind = function (context,/*args*/) {
const _this = this, args = Array.prototype.slice.call(arguments, 1);
function main() {
_this.apply(context, args);
};
if (_this.prototype) {
main.prototype = Object.create(_this.prototype);
} else {
let F = function () { };
F.prototype = _this;
main.prototype = new F();
}
return main;
};
class Person {
constructor(config) {
Object.assign(this, config);
}
sayName() {
console.log(this.name);
}
sayAge() {
console.log(this.age);
}
};
class Student extends Person {
constructor(config) {
super(config);
}
introduce() {
this.sayName();
this.sayAge();
console.log('hello everyone!');
}
}
const student = new Student(
{
name: '任先阳',
age: 18,
}
);
const introduce = student.introduce.myBind(student);
introduce();
2、谈一下函数节流(throttle)与防抖(debounce)?
- 限制函数运行次数
- 防抖,函数只允许一次;节流,函数运行多次
- 防抖,依赖定时器;节流则有多种实现方式
-
定时器版本的函数节流不推荐哈,可以看到为了控制是否立即执行,多了一堆奇奇怪怪的代码
const utils = {};
utils.debounce = function (fn, delay) {
let timer = null;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(fn, args);
}, delay);
};
};
utils.diffThrottle = function (fn, delay, immediate = true) {
let lastTime = immediate ? +new Date() : null, currentTime = null;
return function (...args) {
currentTime = +new Date();
if (lastTime && currentTime - lastTime <= delay) return;
lastTime = currentTime;
fn.apply(fn, args);
};
};
//定时器版本的函数节流不推荐哈,可以看到为了控制是否立即执行,多了一堆奇奇怪怪的代码
utils.timerThrottle = function (fn, delay, immediate = true) {
let execFlag = true;
return function (...args) {
if (!execFlag) return;
execFlag = false;
if (immediate) {
immediate = false;
return main(args);
}
setTimeout(main, delay);
};
function main(args) {
fn.apply(fn, args);
execFlag = true;
}
};