1.函数的概念
就是封装了一段可被重复调用执行的代码块。通过代码块可以实现大量代码的重复利用。
函数的作用:
功能的封装,直接调用,代码复用率提高
2.函数声明
函数是由function关键字声明,声明函数的方式有两种:
方式一:
function 函数名(形参列表){
//函数体
}
方式二:
var 函数名 = function(形参列表){
//函数体
}
3.函数调用
函数本身是并不会执行代码,只有调用函数才会执行函数体代码。
// 调用函数
// 函数名(); 通过调用函数来执行函数体代码
function niHao() {
console.log ('hello');
}
niHao();
调用函数的方式不仅限于()执行,还有其他几种方式
-
函数名.call(执行环境对象,实参列表);
-
函数名.apply(执行环境对象,实参列表数组);
3.1 call(执行环境对象,实参列表);
调用call方法,第一个参数就是要把b添加到哪个环境中,简单来说,this就会指向那个对象。
var obj = {
name: 'lisi',
sayName: function () {
console.log(this.name);
}
}
var b = obj.sayName;
b.call(obj); // lisi
var obj = {
name: 'lisi',
sayName: function (a,b) {
console.log(this.name);
console.log(a,b); // 1,2
}
}
var b = obj.sayName;
b.call(obj,1,2); // lisi 使用call调用时,可以传多个参数
3.2 apply(执行环境对象,实参列表数组);
apply方法和call方法有些相似,它也可以改变this的指向3.3 bind(执行环境对象)(实参列表);
var obj = {
name: 'lisi',
sayName: function () {
console.log(this.name);
}
}
var b = obj.sayName;
b.bind(obj); // 代码没有被打印,这就是bind和call、apply方法的不同,
// 实际上bind方法返回的是一个修改过后的函数。
// 新建一个变量c来接收bind修改后的函数
var c = b.bind(obj);
console.log(c); // 发现c是一个[Function: bound sayName]函数
// 执行c
c(); // lisi
4. Arguments
当我们不确定有多少个参数传递的时候,可以用arguments来获取。在JavaScript中, arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象, arguments对象中存储了传递的所有实参。
arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:
● 具有length属性
● 按索引方式储存数据
● 不具有数组的push, pop等方法
arguments是一个类数组(并不是真正的数组)对象,包含着传入函数中的所有参数。arguments主要用途是保存函数参数。
// 示例
function Arr() {
console.log(arguments);
// 输出:[Arguments] { '0': 3, '1': 6, '2': 8, '3': 4, '4': 5 }
console.log(arguments.length); // 输出 5
}
Arr(3,6,8,4,5);
5. IIFE
IIFE: Immediately Invoked Function Expression,意为立即调用的函数表达式,也就是说,声明函数的同时立即调用这个函数。
作用:
1. 页面加载完成时值执行一次的设置函数。
2. 将设置函数中的变量包裹在局部作用域中,不会泄露成全局变量。
IIFE的函数调用形式:
(function(){
var num = 3;
console.log(num);
})(); // 括号里面可以传递参数
IIFE的常用两种写法:
// 写法1
(function(形参){
函数体内容
})(实参);
// 写法2
(function(形参){
函数体内容
}(实参));
6.回调函数
setTimeout() 这个函数叫做回调函数 callback
普通函数是按照代码的顺序直接调用,而这个函数需要等待时间,时间到了才去调用这个函数,因此称为回调函数。
简单理解:回调,就是回头调用的意思。上一件事干完,再回头再调用这个函数
//定义主函数,回调函数作为参数
function A(callback) {
callback();
console.log('我是主函数');
}
//定义回调函数
function B() {
// 模仿延时操作/异步操作
setTimeout(() => {
console.log('我是回调函数');
}, 3000);
}
//调用主函数,将函数B传进去
A(B);
7. 闭包
简单讲,闭包就是指有权访问另一个函数作用域中的变量的函数。
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
闭包的生成有三个必要条件(具体请查阅资料)
1. 函数嵌套函数
2. 内部函数引用了外部函数中的数据(属性、函数)
3. 参数和变量不会被回收(通常函数执行一次就会被垃圾机制回收)
这样就形成了一个不会销毁的函数空间
function func() {
var a = 9, b = 5;
function closure() {
return a - b;
}
return closure;
}
console.log(func()()); // 4