272 函数的理解和使用:回调函数,匿名函数自调用IIFE,函数中的this
-
什么是函数?
- 用来实现特定功能的, n条语句的封装体
- 只有函数类型的数据是可以执行的, 其它的都不可以
-
为什么要用函数?
- 提高复用性
- 便于阅读交流
-
函数也是对象
- instanceof Object===true
- 函数有属性: prototype
- 函数有方法: call()/apply()
- 可以添加新的属性/方法
-
函数的3种不同角色
- 一般函数 : 直接调用
- 构造函数 : 通过new调用
- 对象 : 通过.调用内部的属性/方法
-
函数中的this
- 显式指定谁: obj.xxx()
- 通过call/apply指定谁调用: xxx.call(obj)
- 不指定谁调用: xxx() : window
- 回调函数: 看背后是通过谁来调用的: window/其它
-
匿名函数自调用:
(function(w, obj){ //实现代码 })(window, obj)
- 专业术语为: IIFE (Immediately Invoked Function Expression) 立即调用函数表达式
-
回调函数的理解
- 什么函数才是回调函数?
- 你定义的
- 你没有调用
- 但它最终执行了(在一定条件下或某个时刻)
- 常用的回调函数
- dom事件回调函数
- 定时器回调函数
- ajax请求回调函数(后面讲解)
- 生命周期回调函数(后面讲解)
- 什么函数才是回调函数?
函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>04_函数</title>
</head>
<body>
<!--
1. 什么是函数?
* 实现特定功能的n条语句的封装体
* 只有函数是可以执行的, 其它类型的数据不能执行
2. 为什么要用函数?
* 提高代码复用
* 便于阅读交流
3. 如何定义函数?
* 函数声明
* 表达式
4. 如何调用(执行)函数?
* test(): 直接调用
* obj.test(): 通过对象调用
* new test(): new调用
* test.call/apply(obj): 临时让test成为obj的方法进行调用
-->
<script type="text/javascript">
/*
编写程序实现以下功能需求:
1. 根据年龄输出对应的信息
2. 如果小于18, 输出: 未成年, 再等等!
3. 如果大于60, 输出: 算了吧!
4. 其它, 输出: 刚好!
*/
function showInfo(age) {
if (age < 18) {
console.log('未成年, 再等等!')
} else if (age > 60) {
console.log('算了吧!')
} else {
console.log('刚好!')
}
}
showInfo(17)
showInfo(20)
showInfo(65)
function fn1() { //函数声明
console.log('fn1()')
}
var fn2 = function() { //表达式
console.log('fn2()')
}
fn1()
fn2()
var obj = {}
function test2() {
this.xxx = 'haha'
}
// obj.test2() 不能直接, 根本就没有
test2.call(obj) // obj.test2() // 可以让一个函数成为指定任意对象的方法进行调用
console.log(obj.xxx) /// haha
</script>
</body>
</html>
回调函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>05_回调函数</title>
</head>
<body>
<button id="btn">测试点击事件</button>
<!--
1. 什么函数才是回调函数?
1). 你定义的
2). 你没有调
3). 但最终它执行了(在某个时刻或某个条件下)
2. 常见的回调函数?
* dom事件回调函数 ==>发生事件的dom元素
* 定时器回调函数 ===>window
* ajax请求回调函数(后面讲)
* 生命周期回调函数(后面讲)
-->
<script type="text/javascript">
document.getElementById('btn').onclick = function() { // dom事件回调函数
alert(this.innerHTML)
}
//定时器
// 超时定时器
// 循环定时器
setTimeout(function() { // 定时器回调函数
alert('到点了' + this)
}, 2000)
/*var a = 3
alert(window.a)
window.b = 4
alert(b)*/
</script>
</body>
</html>
自调用函数IIFE
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>06_IIFE</title>
</head>
<body>
<!--
1. 理解
* 全称: Immediately-Invoked Function Expression
2. 作用
* 隐藏实现
* 不会污染外部(全局)命名空间
* 用它来编码js模块
-->
<script type="text/javascript">
(function() { //匿名函数自调用
var a = 3;
console.log(a + 3);
})();
var a = 4;
console.log(a);
;
(function() {
var a = 1;
function test() {
console.log(++a);
}
window.$ = function() { // 向外暴露一个全局函数
return {
test: test
}
}
})();
$().test(); // 1. $是一个函数 2. $执行后返回的是一个对象
</script>
</body>
</html>
函数中的this
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>07_函数中的this</title>
</head>
<body>
<!--
1. this是什么?
* 任何函数本质上都是通过某个对象来调用的,如果没有直接指定,就是window
* 所有函数内部都有一个变量this
* 它的值是调用函数的当前对象
2. 如何确定this的值?
* test(): window
* p.test(): p
* new test(): 新创建的对象
* p.call(obj): obj
-->
<script type="text/javascript">
function Person(color) {
this.color = color;
console.log('此时的this是:', this);
// console.log(this.color);
this.getColor = function() {
console.log(this)
return this.color;
};
this.setColor = function(color) {
console.log(this)
this.color = color;
};
console.log('哈哈,此时的this是:', this);
}
Person("red"); //this是谁? window 【控制台输出 此时的this是: Window】
new Person('pink'); // Person {color: "pink"} 【因为new的最后会返回创建的新对象。】
var p = new Person("yello"); // this是谁? p 【Person {color: "yello"}】
console.log('p是:', p); // p是: Person {color: "yello", getColor: ƒ, setColor: ƒ}
p.getColor(); //this是谁? p 【Person {color: "yello", getColor: ƒ, setColor: ƒ}】
var obj = {
aa: 11
};
p.setColor.call(obj, "black"); // this是谁? obj 【{aa: 11}】
// 【(1)把p.setColor函数的内存地址复制给test,test指向p.setColor函数;(2)用var声明的变量都将成为window的属性。】
var test = p.setColor;
test(); // this是谁? window
function fun1() {
function fun2() {
console.log(this); // window
}
fun2(); //this是谁? window
}
fun1();
</script>
</body>
</html>