函数概念
- 实现特定功能的n条语句的封装体
- 只有函数是可以执行的,其它类型的数据不能执行
使用函数的优点
- 提高代码复用
- 便于阅读交流
定义函数
- 函数声明
- 表达式
// 函数声明
function showInfo(age){
if(age<18){
console.log("未成年,再等等吧")
}else if(age>60){
console.log("好好享受生活吧")
}else{
console.log("年龄合适!")
}
}
showInfo(34)
//表达式调用
var fun2 = function(a,b){
return a+b;
}
console.log(fun2(2,3))
调用(执行)函数
- 直接调用:
函数名(参数)
- 通过对象调用:
对象名.函数名
- new调用:
new 函数名()
——构造函数 - 临时让函数成为对象的方法进行调用:
函数名.call/apply(对象名)
——JS独有的。
eg:
var obj={
}
function fun(){
this.name='baidu'
}
fun.call(obj)//就相当于obj调用了fun函数
console.log(obj.name)
输出:
baidu
回调函数
回调函数的定义
1).你定义的
2).你没有调
3).但最终它执行了(在某个时刻或某个条件下)
这样的函数被称为回调函数
回调函数的分类
分类 | 对应的this |
---|---|
dom事件回调函数 | 发生事件的DOM元素 |
定时器回调函数 | window |
ajax请求回调函数 | |
生命周期回调函数 |
eg:
// dom事件回调函数
document.getElementById("btn").onclick = function(){
alert(this.innerHTML)
}
// 定时回调函数
setTimeout(function(){
alert('我是定时器回调函数')
},2000)
IIFE
定义
全称:ImmediateLy-Invoked Function Expression 立即调用函数表达式
就是将函数立即执行,需要和匿名函数一起使用。
使用方式:(匿名函数)()
eg:
(function(){
console.log('我是匿名函数自调用')
})()
这样写其实就是匿名函数的自调用
,所以说 IIFE其实就是匿名函数的自调用。
匿名函数的自调用完整格式:(function(形参){})(实参)
优点
- 隐藏实现
- 不会污染外部(全局)命名空间
在匿名函数的自调用中定义的变量是局部变量所以不会污染外部(全局)命名空间。 - 用它来编码js模块
eg:
(function(){
var a =1;
function test(){
console.log(++a)
}
window.$ = function(){
// 返回一个配置对象
return{
test:test
}
}
})()
$().test()
// $是一个函数
// $执行后返回的是一个配置对象,test属性是一个函数
输出:
2
函数中的this
任何函数本质上都是通过某个对象
来调用的,如果没有直接指定就是window
所有函数内都都有一个变量this,它的值是调用函数的当前对象
总结如下:
- 以函数形式调用时, this永远都是window
- 以方法的形式调用时, this是调用方法的对象
- 以构造函数的形式调用时,this是新创建的那个对象
- 使用call和apply调用时, this是指定的那个对象
eg:
function Person(color){
console.log(this)
this.color =color;
this.getColor = function(){
console.log(this)
return this.color;
}
this.setColor = function(color){
console.log(this)
this.color = color;
}
}
// 当作函数
Person("red"); //this 是 window,以函数形式调用时, this永远都是window
// 当作构造函数
var p =new Person("yellow"); //this 是 p
p.getColor();//this 是 p
var obj ={}
p.setColor.call(obj,"black");//this 是 obj
var test = p.setColor;
test();//this 是 window
function fun1(){
function fun2(){
console.log(this);//this 是 window
}
}
补充:关于加不加分号的问题
可以加也可以不加,依喜好而定。
但是在下面2种情况下不加分号会有问题
- 小括号开头的前一条语句
- 中方括号开头的前一条语句
遇到这两种情况在行首加一个分号可以
eg:
var a =3
;(function(){
})()
var a =3
;[1,2].forEach(function(){
});