大家好,我是阿赵。继续学习JavaScript。这次学习一下函数的进阶用法。
一、 闭包
一个函数对周围状态的引用捆绑在一起,内存函数中访问到其外层函数的作用域。
闭包 = 内存函数 + 外层函数变量。
例子:
function fn() {
const num = 10;
function fn1() {
console.log(num);
}
return fn1;
}
在这个例子里面,num本身是函数fn定义的常量,然后被fn1使用了。然后把fn1返回给更外部使用,导致了在fn1外部的常量num,被包含在了fn1函数里面了。
在外部调用这个返回的fn1的时候,实际上是访问到了fn定义的变量或者常量。
所以,闭包的作用是:
封闭数据,提供操作,让外部也可以访问函数内部的变量。实现了数据的私有化。
不过闭包也会产生内存泄漏的风险。
二、 不定参数
之前学习函数的时候,一般需要在声明的时候把形参的数量写好。但有时候形参的数量不能确定,就需要用不定参数。
1、 动态参数
例子:
function sum() {
console.log(arguments);
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
结果:

可以看到,sum函数并没有声明参数,但在运行的时候,通过argumengts来获取到了实际参数。
arguments是一个伪数组,只存在于函数中,作用是动态获取函数实参。
可以通过循环语句依次得到传递的实参。
不管函数本身是否声明了变量,用arguments拿到的参数数组,都是所有的参数,比如:
function sum(num1, num2) {
console.log(arguments);
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
结果:

2、 剩余参数
例子:
function sum(...args) {
console.log(args);
var sum = 0;
for (var i = 0; i < args.length; i++) {
sum += args[i];
}
return sum;
}
console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
结果:

允许将一个不定数量的参数表示成一个数组,写法是…变量名。由于这个是一个真实的参数,所以还可以和其他参数配搭着用。
例子:
function sum(num1, num2, ...args) {
console.log(args);
var sum = 0;
for (var i = 0; i < args.length; i++) {
sum += args[i];
}
return sum;
}
console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
结果:

可以看到,sum函数声明了num1和num2,那么…args这个变量代表的就是除了num1和num2,剩下的部分参数。
3、 展开运算符
例子:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const arr2 = [...arr];
console.log(arr2);
结果:

特点:展开运算符不会修改原数组,而是把原数组展开,变成新数组。
比如,如果用max函数取数组最大值,需要这样写:
console.log(Math.max(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
如果写成这样:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(Math.max(arr));
是不行的:

但如果写成这样:
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(Math.max(...arr));
是可以的。这就是所谓展开。
另外一个例子:
const arr1 = [1, 2, 3, 4, 5];
const arr2 = [6, 7, 8, 9, 10];
const arr3 = [...arr1, ...arr2];
console.log(arr3);
结果:

三、 箭头函数
1、基础使用
例子:
const fn = (x) => {
console.log(x);
}
fn(100);
这里没有像之前那样写function,只是简单的
(参数)=>{}
代表了一个函数。
箭头函数比正常函数表达式更简洁,更适合用于本来需要匿名函数的地方。
2、简写
如果只有一个形参的时候,可以省略小括号,比如
const fn = x=>{
console.log(x);
}
如果函数只有一行,可以写到一行上,并且不需要写return,直接返回值,比如
const fn = x => x+x;
用法举例:
原来监听事件是这样写:
const form = document.createElement(“form”);
form.addEventListener(‘click’, function (e) {
e.preventDefault();
});
那么简写之后,可以是
const form = document.createElement("form");
form.addEventListener('click', e => e.preventDefault())
4、 不定参数
箭头函数没有arguments,但有剩余参数…args。
例子:
const fn = (...args) => {
console.log(args);
}
fn(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
结果:

5、 this
箭头函数不会创建自己的this,只会从自己作用域链的上一层沿用this


被折叠的 条评论
为什么被折叠?



