📌 立即执行函数IIFE(immediately invoked function expression)
立即执行函数 创建后立即执行,本质是函数表达式
- 页面加载自动执行,执行完成立即销毁(故忽略函数名) ```javascript //第一种写法——————————— (function(){ … })();
//第二种写法【W3C建议写法】——————————- (function(){ … }());
**函数**只要**以表达式形式**出现,无论**有名与否**,无论**执行与否**,其**自动忽略函数名**,通过函数名**调用会报错**,typeof检测**类型为undefined **> **注意:错误写法——报语法错误**> ** Uncaught SyntaxError: Unexpected token ")" **```javascript//错误的写法function (){...}(); //报错: Uncaught SyntaxError: Unexpected token (
- 错误原因
- 一定是表达式才能被执行符号执行
- 语句后的()会被当做分组操作符,分组操作符里不能未空必须有表达式,所以报错
- 即使()内有值或表达式,JavaScript引擎会将其当作单独的表达式来解析,不报错,函数因未被调用而不会执行
- 因其执行完成立即销毁,所以立即执行函数忽略函数名(在其外部使用函数名调用报错未定义)
//让Javascript引擎认为这是一个表达式的方法还有很多!function(){}();+function(){}();-function(){}();~function(){}();0 || function(){}();1 && function(){}();new function(){ /* code */ }new function(){ /* code */ }() // 只有传递参数时,才需要最后那个圆括号
- 一定是表达式才能被执行符号执行
经典实用场景案例 利用立即执行函数弹出对应事件索引
<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>利用立即执行函数弹出对应事件索引</title></head><body><ul><li>点击,打印0</li><li>点击,打印1</li><li>点击,打印2</li><li>点击,打印3</li><li>点击,打印4</li></ul><script>var lis = document.querySelectorAll("li")for (var i = 0; i < lis.length; i++) {(function (j) {lis[j].addEventListener('click', function () {console.log(j);})}(i))}</script></body></html>
立即执行函数 和 闭包 的区别 ? 两者经常会结合在一起使用,但其两者本质不同
- **共同点**:
- 可以减少全局变量的使用
- 不同点**:**
- 立即执行函数:声明之后立即执行,一般只调用一次后立即销毁,不占内存空间
- 闭包:让外部可以访问其内部作用域,保证内部变量安全,但其内部变量被引用无法销毁,增加了内存消耗,可能造成内存泄漏
📌 逗号运算符
逗号运算符 执行所有的操作数,只返回最后一个操作数的值 逗号运算符在JavaScript中的优先级是最低的
- 单一var声明模式,多个变量连续赋值 ```javascript var a = 1,b = 2,c = 3,d = 4;
// 等价于———————————————— var a = 1; var b = 2; var c = 3; var d = 4;
- **逗号运算符可用于赋值,返回表达式中的最后一项**```javascriptvar num = (1,2,3,4,5);console.log(num); // 5
- 常用于for循环中,可循环多个变量
for(var i= 0,j = 10; i < j; i++, j--){console.log(i + j) // 10 10 10 10 10};
📋 课后作业
1、累加器,初始值0,利用闭包,执行闭包函数,每执行一次+1 2、缓存器,利用闭包,学生名保存在数组里,两个方法写在函数的对象中, 方法一功能加入班级,方法二功能离开班级,每次加入或离开都需答应班级人员新名单
// 累加器,初始值0,利用闭包,执行闭包函数,每执行一次+1function accumulation() {var init = 0;return function () {init++console.log(init);}}var add = accumulation()add(); //1add(); //2add(); //3add(); //4add(); //5-------------------------------------------------------------/**缓存器,利用闭包,学生名保存在数组里,两个方法写在函数的对象中*功能方法一加入班级,*功能方法二离开班级,*每次加入或离开都需打印班级人员新名单*/function cache() {var students = [];function add(newName) {students.push(newName)console.log('欢迎' + '【' + newName + '】' + '同学加入!' + '目前班级人员名单如下:');for (var i = 0; i < students.length; i++) {console.log(students[i]);}}function leave(oldName) {var idx = students.indexOf(oldName)if (idx == -1) return console.log('----查无此人----');students.splice(idx, 1)console.log('送别' + '【' + oldName + '】' + '同学!' + '目前班级人员名单如下:');if (students.length <= 0) return console.log('班级人数已经清0,目前已无人员信息');for (var j = 0; j < students.length; j++) {console.log(students[j]);}}return { add, leave }}var res = cache()res.add('张三') //欢迎【张三】同学加入!目前班级人员名单如下:张三res.add('王五') //欢迎【王五】同学加入!目前班级人员名单如下:张三 王五res.add('李四') //欢迎【李四】同学加入!目前班级人员名单如下:张三 王五 李四res.leave('小李') //----查无此人----res.leave('张三') //送别【张三】同学!目前班级人员名单如下:王五 李四res.leave('李四') //送别【李四】同学!目前班级人员名单如下:王五res.leave('王五') //送别【王五】同学!目前班级人员名单如下:班级人数已经清0,目前已无人员信息res.leave('张三') //----查无此人----
