大前端课程学习心得体会+学习笔记
心得体会
已经学习了两周半的大前端课程了,课程质量真的是好得没话说,我看过很多前端的课程,但从没有哪家课程能将前端的知识体系划分的如此全面细致,还能保证每一个知识点还都能讲得如此透彻,在讲知识点的基础上还能开篇幅去讲思想,更是难得。比如下面的函数式编程,这种编程范式我之前从来都没使用过,更不知道柯里化、函数组合为何物。直到在拉钩大前端课程中,每一个知识点的学习,都让我有种重获新生的感觉,仿佛以前学习的东西都白学了,只知道简单的用法,不了解核心原理,更不会用高级特性。现在每学习完一个模块,就期待着解锁下一个模块,迫不及待地想去知道下一个模块可以让自己get到哪些技能。
课程的主讲老师,汪磊老师,我看过他的webpack专栏,那时我就非常佩服他能够把webpack这样一个大而繁琐的工具,讲得如此细微易懂,让我懂了webpack的插件机制和loader机制。在大前端课程中,汪磊老师更是让我敬佩,我感觉他的知识面非常广,说他什么都懂也不为过,他还总是把我们在学习中会遇到的问题演示出来,或者是提出来让我们注意。最感谢汪磊老师的地方,就是在JS异步章节,直播课中的补充中,老师演示了各种function会影响this问题,道出了this取决于调用而不是定义,让我醍醐灌顶,也彻底搞懂了JS的this的取值,那天晚上令我激动地睡不着觉。
除此之外,两位助教老师还整天在群内答疑,只要遇到不懂的地方,就可以立马去群里问助教老师,老师会看到问题就会立马回复,如果是代码执行问题,还会把你的代码下载下来亲自运行排查,真的是太贴心了。班主任老师会在群里每天督促同学们交作业,遇到软件问题、作业提交问题、听课问题都可以找班主任老师。
一个人学习或许会太孤独,但是在拉钩教育大前端课程里,每天和几百人一起学习,群里还有专业的助教老师答疑,其他同学很多都是前端大佬,在你遇到问题的时候,无论是什么问题,只要是前端问题,总会有人给你解答或者提供思路。
在拉钩教育大前端课程中,一起学习,使彼此共同成长。
函数式编程范式
一、高阶函数
使用高阶函数的意义:抽象可以帮我们屏蔽细节,只需要关注于我们的目标。高阶函数是用来抽象通用的问题。
1. 函数作为参数
function forEach (array, fn) {
for (let i = 0; i < array.length; i++) {
fn(array[i])
}
}
function filter (array, fn) {
const res = []
for (let i = 0; i < array.length; i++) {
if(fn(array[i])) {
res.push(array[i])
}
}
return res
}
const arr = [1, 2, 4, 5, 2]
forEach(arr, console.log)
console.log(filter(arr, function (item) {
return item % 2 === 0
}))
2. 函数作为返回值
function makeFn () {
let msg = 'hello function'
return function () {
console.log(msg)
}
}
const fn = makeFn()
fn() // hello function
makeFn()() // hello function
应用:once函数 只执行一次的函数,比如说支付情况,无论用户点多少次,这个函数都只执行一次
function once(fn) {
let done = false
return function () {
if(!done) {
done = true
fn.apply(this, arguments)
}
}
}
let pay = once(function (money) {
console.log(`支付了${
money}元`)
})
pay(1) // 支付了1元
pay(2)
pay(3)
常用的高阶函数:
forEach/map/filter/every/some/find/findIndex/reduce/sort
// 模拟常用的高阶函数:map every some
const arr = [1, 2, 3, 4]
// map
const map = (arr, fn) => {
let result = []
for(let item of arr) {
result.push(fn(item))
}
return result
}
console.log(map(arr, val => val * val)) // [ 1, 4, 9, 16 ]
// every
const every = (arr, fn) => {
for(let item of arr) {
if(!fn(item))return false
}
return true
}
console.log(every(arr, v => v > 0)) // true
// some
const some = (arr, fn) => {
for(let item of arr) {
if(fn(item))return true
}
return false
}
console.log(some(arr, v => v % 2 == 0)) // true
二、闭包
函数和其周围的状态(词法环境)的引用捆绑在一起形成闭包。可以在一个作用域中调用一个函数的内部函数并访问到该函数的作用域中的成员。
本质:函数在执行的时候会放到一个执行栈上,当函数执行完毕之后会从执行栈移除,但是堆上的作用域成员因为外部引用不能释放,因此内部函数依然可以访问外部函数的成员
function makeFn () {
let msg = 'hello function'
return function () {
console.log(msg)
}
}
const fn = makeFn()
fn() // hello function
闭包的应用:
function makePower(power) {
return function (num) {
return Math.pow(num, power)
}
}
// 求平方
let power2 = makePower(2)
let power3 = makePower(3)
console.log(power2(4))
console.log(power2(5))
console.log(power3(4))
三、纯函数
-
相同的输入永远会得到相同的输出
-
没有任何可观察的副作用
-
类似数学中的函数
-
lodash是一个纯函数的功能库,提供了对数组、数字、对象、字符串、函数等操作的一些方法
-
数组的slice和splice分别是纯函数和不纯的函数
- slice返回数组中的指定部分,不改变原数组
- splice对数组进行操作返回该数组,会改变原数组
// 纯函数slice和不纯函数splice let arr = [1, 2, 3, 4, 5] console.log(arr.slice(0, 3)) console.log(arr.slice(0, 3)) console.log(arr.slice(0, 3)) console.log(arr.splice(0, 3)) console.log(arr.splice(0, 3)) console.log(arr.splice(0, 3)) function getSum(n1, n2) { return n1 + n2 } console.log(1, 2) console.log(1, 2) console.lo