1.什么是函数?
function(){}
const bar = function(){}
- 由 function 关键词进行定义;
- 函数名称标识符,类似变量的名字;
- 圆括号,可能含有若干个以逗号隔开的参数;
- 花括号,函数体。
函数的调用方法:
- 函数的定义上,会包括一个成为形参(parameter)的标识符列表,这些参数在函数体中,像局部变量一样的工作;
1.作为函数调用
function foo(){}
foo()
2.作为方法的调用
const bar = {
foo(){
console.log(this.name)
},
name:'wzj'
}
bar.foo()//'wzj'
global.name = 'global'
const foo = bar.foo;
foo()//'global'
3.作为构造函数调用
const Bar = function(name,fn){
this.name = name;
this.handler = fn;
}
const bar = new Bar('bar',function(){
console.log(this.name)//'bar'
})
const bars = new Bar('bar',()=>{
console.log(this.name)//'undefined'
})
console.log(bar,bars)
bar.handler()
4.被call 或 apply 调用
const bar = {
//bar 这个对象,有个函数,叫做foo,可以打印对象调用者的名字和参数
foo(params){
console.log(this.name,params)
},
name:'wzj'
}
// 假如,有一个对象叫做obj,这个obj想要使用这个bar 的 foo方法
// 但是我没有,只能‘借用’
const obj = { name:'simple-obj'}
bar.foo.call(obj,'objparams')
实参和形参
形参
function foo(params){}//params 形参
形参特点:
- JavaScript 语言本身,既没有给形参限制类型,也没有给形参做类型检查。
- JS 是没有重载的。 重载在java中指一个类中可以有多个相同名称的方法,但这些方法的参数不同。
- 形参是可选的。我传入的实参,既可以比形参多,也可以比形参少。
- 当我的实参传入少于形参的时候,按顺序走,多出来的,是 undefined
function createPerson(name,age,isMale){
return {
name,age,sex:isMale ? 'male' : 'female'
}
}
console.log(createPerson('wzj','',true))
function createPerson2({name,age,isMale}){
return {
name,age,sex:isMale ? 'male' : 'female'
}
}
console.log(createPerson2({name:'wzj',isMale:true}))
2.当我传入的实参多于形参时,1.arguments 2. ... 拓展符
实战:写一个无限加法
function add(...rest){
return rest.reduce((total,item)=>total + item,0)
}
function add2(){
return Array.prototype.reduce.apply(arguments,[(total,item)=>total + item,0])
}
console.log(add(1,2,3,4,5))
console.log(add2(1,2,3,4,5))
高阶函数
//函数作为值
function square(x){return x*x}
const a = square;
console.log(square(2))
console.log(a(2))
//函数作为参数
function caculate(param,cb){
setTimeout(()=>{
const res = param * param
cb(res)
},200)
}
caculate(12,(res)=>{
console.log(res)
})
//函数作为返回值
function discout (ratio) {
return function (price) {
console.log(ratio * price)
}
}
discout(0.75)(10)
//形成了一个闭包
//当一个函数内部的子函数,没有在函数内部执行,而是在外部执行的时候,就形成了闭包
//作用域, - 变量查找的一套规则
//防抖与节流
function debounce (fn, delay = 300) {
let timer = null;
return function () {
let args = arguments;
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(this, args)
}, delay)
}
}
function foo () {
console.log('nihao')
}
const dfoo = debounce(foo, 300)
dfoo()
function throttle(fn,delay=300){
let flag = true;
return function(){
if(!flag)return
flag = false
setTimeout(()=>{
fn()
flag = true
},delay)
}
}
const tfoo = throttle(foo, 300)
tfoo()