这是我参与「第四届青训营 」笔记创作活动的的第四天
写好JS的三个原则
- 各司其职:让css,js,html,职能分离,尽量不要耦合,避免像js操控css修改样式的情况,可用class表示状态,纯展示类交互寻求零JS方案
- 组件封装:让某个功能的所有css,js,html代码封装在一个组件内,让组件有更好的正确性、扩展性和复用性。实现组件的三大步骤:结构设计,展现效果,行为设计;三次重构:插件化、模板化、抽象化。
- 过程抽象:应用函数式编程的思想,比如一些处理局部细节的方法
高阶函数:HOF
- 以函数为参数
- 以函数为返回值
- 常用于用作函数装饰器
常用的五种HOF
1. once函数:只能执行一次有效
function once(fn) {
return function(...args) {
if(fn) {
const ret = fn.apply(this, args);
fn = null;
return ret;
}
}
}
2. throttle函数:节流函数,规定时间内只有一次有效
function throttle(fn, time = 500){
let timer;
return function(...args){
if(timer == null){
fn.apply(this, args);
timer = setTimeout(() => {
timer = null;
}, time)
}
}
}
3. deboubce函数:防抖函数,短时间内多次点击只有最后一次有效
function debounce(fn, dur){
dur = dur || 100;
var timer;
return function(){
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, dur);
}
}
4. consumer函数:同步函数装饰为异步,可以延时调用,比如应用在点赞功能上
function consumer(fn, time){
let tasks = [],
timer;
return function(...args){
tasks.push(fn.bind(this, ...args));
if(timer == null){
timer = setInterval(() => {
tasks.shift().call(this)
if(tasks.length <= 0){
clearInterval(timer);
timer = null;
}
}, time)
}
}
}
5. iterator函数:传入可迭代参数可批量操作
function iterative(fn) {
return function(subject, ...rest) {
if(isIterable(subject)) {
const ret = [];
for(let obj of subject) {
ret.push(fn.apply(this, [obj, ...rest]));
}
return ret;
}
return fn.apply(this, [subject, ...rest]);
}
}
小知识
- this的四种绑定方法:
- 默认绑定:window如:
fn() - 隐式绑定:函数引用的上下文对象决定。如:
a.fn() - 显示绑定:call,apply,bind方法:
call与apply的区别不大:
fn.call(obj,a,b,c);fn.apply(obj,[a,b,c])call与bind的区别:call函数会立即调用,bind只会返回一个可调用的函数 如:fn.call(obj,a,b,c),fn.bind(obj,a,b,c)()` - new绑定:每次调用构造函数的this为当前创造的对象。如:let
a=new Fn();{this为a}
- 四种方法的优先级比较 new>显式>隐式>默认
- new:当我们使用
obj=new Fn()的时候,发生了什么:
- 创建了一个新对象
- 为新对象的__proto__属性赋值为构造函数prototype属性的值
- 将构造函数的作用域赋值给新对象,即
Fn.call(obj),将this指向新对象obj - 执行构造函数内的代码,为新对象添加属性 5.返回新对象
- 箭头函数
- 没有自己的上下文,this都是外部的
- 由于没有自己的上下文,所以不能作为构造函数被new关键字使用
- 没有arguments,和this一样是外部的
算法
前端工程师也是工程师,工程师离不开算法,即使是前端的算法相对其他工程师岗位没那么深入,但也要刷题去专研,要想拿大公司的offer必须要注意。