回调函数:
执行完一个动作之后还要继续执行的函数
作为实参传递的函数就是回调函数
function a() {
console.log(123);
}
function b(fn) {
// fn: 形参 函数 回调函数
console.log(fn);
fn();
}
b(a);
匿名函数
匿名: 没有名字的函数
直接写会报错 将匿名函数转换成函数表达式 外面加() 同样具有函数的特点
立即执行函数: IIFE
-
函数自执行
使用: 团队协作
注意: 分号必须加 不能省略
(function () { console.log('匿名函数'); })(); (function () { console.log('匿名函数1'); }());
有参数
(function (a, b) { console.log(a, b); console.log(arguments); })(10, 20);
有函数返回值
var res = (function () { return true; })(); console.log(res);
闭包
概念
闭包: 可以访问其他函数内部变量的函数就是闭包
组成: 函数里面套函数 内部函数访问外部函数的变量
优点: 扩大变量的作用范围 缓存数据
缺点: 如果有大量缓存数据 会造成内存泄漏 不参与垃圾回收机制
调试:
使用断点调试
\1. outer的第一行代码
\2. inner的第一行代码
\3. 刷新 看右侧或者底部的 Scope
local: 当前作用域
Global: 全局
closure: 闭包
注意: 外部函数调用一次就会形成一个新的闭包
function outer() { var a = 10; function inner() { a++; console.log(a); } // 设置返回值 return inner; } var res = outer(); console.log(res); // inner函数 res(); // 11 res(); // 12 // 外部函数调用一次就会形成一个新的闭包 var res1 = outer(); res1();
使用
当当前作用域需要自己的变量值的时候 使用闭包
在for循环所添加的事件中 解决不能通过下标得到正确的元素的问题
var lis = document.querySelectorAll('li'); console.log(lis); // for(var i = 0; i < lis.length; i++){ // lis[i].onclick = function () { // console.log(i); // 10 // }; // } for(var i = 0; i < lis.length; i++){ (function (s) { // console.log(s); lis[s].onclick = function () { console.log(s); }; })(i); }
模拟私有变量
// 创建账号 function create(val) { var user = val; // console.log(user); // 如果想要在函数外读取或者设置 必须通过当前函数提供的专用函数来实现效果 return { getUser: function () { console.log(user); }, setUser: function (v) { user = v; } }; } var u = create('小时候超白'); console.log(u); u.getUser(); u.setUser('长大后超黑'); u.getUser(); // 与上面的user无关 user = '中年时候超胖'; console.log(user); u.getUser();
面试题
-
输出结果
function fun(n, o) { console.log(o); return { "fun": function (m) { return fun(m, n); } } } /* var a = fun(n, o)--> fun(0) --> n = 0 o = undefined a = {fun: function(m){ }} a.fun(1) m = 1 fun(m, n) m = 1 n = 0 fun(1, 0) --> fun(n, o) n = 1 o = 0 log(o) --> 0 a.fun(2) m = 2 fun(m, n) m = 2 n = 0 fun(2, 0) --> fun(n, o) n = 2 o = 0 log(o) --> 0 a.fun(3) m = 3 fun(m, n) m = 3 n = 0 fun(3, 0) --> fun(n, o) n = 3 o = 0 log(o) --> 0 */ var a = fun(0); // undefined a.fun(1); // 0 a.fun(2); // 0 a.fun(3); // 0
输出结果和执行顺序
for(var i = 0; i < 5; i++){ setTimeout(function () { console.log(i, new Date(), new Date().getTime()); // 5 当前时间+1s }, 1000); } console.log(i, new Date()); // 5 /* 同步: 当前代码执行的时候 后续的代码等着 alert for 异步: 当前代码执行的时候 后续代码不等待执行完成 就可以直接执行 定时器 */
代码分类
同步: 当前代码执行的时候 后续的代码等着 alert for
异步: 当前代码执行的时候 后续代码不等待执行完成 就可以直接执行 定时器