函数的环境
什么是函数?
最开始程序员写的程序大部分是汇编,后来有C语言C++等,这个阶段没有函数的概念,但有一个子程序的概念,(几行代码完成一个功能,给这几行代码起个名字,那时候不叫函数,叫子程序)
数学中的函数
数学中的函数有三个要素:定义域(A),值域(B),法则(f) 假设函数为f,假设输入A集合中的某个值,那么必定有一个输出B集合中的某个值
f(A[3])=B[3] //一旦规则确定,不管你输入多少次A[3],输出都是B[3]
f() //在数学中是不合法的,因为没有输入
如果你的函数符合数学函数的定义,就是函数式的
函数中的返回值是由什么确定的
调用时输入的参数params
定义时的环境env
闭包
闭包能让一个函数维持住一个变量,但并不能维持这个变量的值
对象也可以维持住一个变量,如果一门语言不支持闭包,你可以用对象
let obj = {
i: 0,
fn() {
this.i += 1
console.log(`我是obj的闭包i:${this.i}`)
}
}
const handle = function () {
let i = 0
return function () {
i++
console.log(`我是实例化的闭包i:${i}`)
}
}
obj.fn()
obj.fn()
let fn2 = handle()
fn2()
fn2()
this的值
如果你不知道什么是this
请参考阮一峰老师的文章
箭头函数this是环境,非箭头函数的this是一个隐式参数
const fn = function (p1, p2) {
console.log(this, p1, p2)
}
fn(1, 2)//隐式传参,不写会自动传undefined
fn.call(undefined, 1, 2)//显示传参,如果为undefined,浏览器会帮我们将this指向全局window
学会call,bind,apply等调用方法指定this,用来加深this的理解
你得知道函数是怎么调用的,你才能确定this的值
递归与记忆化
递归的特点就是自己调用自己,并且有一个结束条件,不然就是无限递归,永远无法拿到结果
所有的递归都可以用循环实现,我们可以认为尾递归是另一种for循环的写法
js中不管我们是否进行了尾递归优化,它都会帮我们压栈,我们可以使用memorize进行函数缓存
memorize实现
const memo = (fn) => {
function memoed(key) {
memoed.cache[key] = memoed.cache[key] || fn.apply(this, arguments)
return memoed.cache[key]
}
memoed.cache = {}
return memoed
}
const x = memo((x) => {
console.log('执行了')
return x * 2
})
console.log(x(1))//第一次进来打印执行了
console.log(x(1))//不会打印,说明没有再次执行传进去的函数,而是直接拿上次缓存的结果
console.log(x(1))//不会打印
console.log(x(1))//不会打印
console.log(x(2))//发现没有缓存,调用函数,缓存函数结果
柯里化
让所有的函数只接受一个参数
单一参数有什么意义?
?
怎么支持两个参数
使用闭包
const add = function (a){
return function(b){
return a+b
}
}
add(1)(2)//输出3
柯里化一个函数
const curring = (fn, params = []) => {
return (arg) => {
const newParams = params.concat(arg)
if (fn.length === newParams.length) {
return fn(...newParams)
} else {
return curring(fn, newParams)
}
}
}
const addTow = (a, b) => a + b
const addThree = (a, b, c) => a + b + c
const newAddTow = curring(addTow)
const newAddThree = curring(addThree)
console.log(newAddTow(1)(2))
console.log(newAddThree(1)(2)(3))
高阶函数
把函数作为参数或返回值的函数就是高阶函数
js内置的高阶函数
Function.prototype.bind
Function.prototype.apply
Function.prototype.call
Function.prototype.sort
Function.prototype.map
Function.prototype.filter
Function.prototype.reduce
function fn (){
console.log(this)
console.log(arguments)
}
bind.call(fn,{name:'tj'},2,3,4)
apply.call(fn,{name:'tj'},[2,3,4])
call.call(fn,{name:'tj'},2,3,4)
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!