函数

函数默认值

1
2
3
4
5
6
7
8
// es5
const show = function (one) {
one = one || 5;
};
// es6
const show = function (one = 5) {};
// one此时默认值就为5
传参的时候如果不想输入,而直接使用默认值,则传过去一个undefined就可以

参数问题

如果函数的接受参数是一个复合对象

则这个参数会指向那个对象的地址

1
2
3
4
5
6
7
8
let obj = {
name: "张三",
sex: "男",
};

const show = function (obj2) {
obj2.name = "李四";
};

此时 obj 的 name 也被修改成李四了;

和这个情况是一样的;

1
2
3
4
5
6
7
8
let obj = {
name: "张三",
sex: "男",
};

let obj2 = obj;

obj2.name = "李四";

qMDnM.png

函数也是对象

回调函数

1
2
3
4
5
6
7
8
9
10
const one = function (str) {
return str.toUpperCase();
};

const two = function (str, fn) {
console.log(str);
console.log(fn(str));
};

two("agecdfg", one);

D0XEg.png

如果当作事件来看,会好理解很多

1
2
btn.addEventListener("click", function () {});
//本身add...就是一个方法(也可以称为函数),第二个参数就是要实现的函数

你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话,过了几天店里有货了,店员就打了你的电话,然后你接到电话后就到店里去取了货。

在这个例子里,你的电话号码就叫回调函数,你把电话留给店员就叫登记回调函数,店里后来有货了叫做触发了回调关联的事件,店员给你打电话叫做调用回调函数,你到店里去取货叫做响应回调事件。

闭包

闭包让你可以在一个内层函数中访问到其外层函数的作用域

1
2
3
4
5
6
7
8
9
const greet = function (string) {
return function (name) {
console.log(string, name);
};
};

console.log(greet("Hello"));
greet("Hello")("小王");
greet2("小王");

D3Hik.png

定义

闭包让你可以在一个内层函数中访问到其外层函数的作用域闭包让你可以在一个内层函数中访问到其外层函数的作用域

闭包是封闭变量,执行上下文的环境,在其中创建了一个函数,即使在那个执行上下文消失之后(即使在函数之后),执行上下文所属的已经返回

闭包使函数可以访问所有变量,其父函数

所以函数保持对其外部范围的引用,即使在那个外部范围消失之后,这基本上保留了整个时间范围链

另一个定义

类比是闭包确保一个函数永远不会失去连接,到函数诞生地存在的变量,它记得变量,即使在出生地消失之后

就像一个不会失去联系的人到他们的家乡,在这个类比当中,人就是函数,而家乡是函数的父范围,然后该功能不会失去连接到存储在此父级范围中的变量

如果没有函数返回值

1
2
3
4
5
6
7
8
9
10
11
12
13
let a;

let b = function () {
let c = 777;
a = function () {
consnole.log(c * 2);
};
};

a(); //会提示未定义

b();当调用完a之后,会关闭b的变量环境
a(); //输出结果是c*2的值

内部作用域的属性在 scopes 里面

closure:获取父函数的的变量

双括号代表是一个内部属性,无法从代码中访问

立即调用函数表达式,简称 IIFE

用括号去欺骗 JavaScript 来进行使用

1
2
3
4
5
(function () {
执行语句;
})();

(() => console.log("123"))();

立即创建,立即调用