JS立即执行函数、逗号操作符
目录
立即执行函数
逗号操作符
一、立即执行函数
- 立即执行函数又叫初始化函数
- 当一个全局函数被声明后,这个函数会一直存在GO里,随时要用都能直接用
- 如果一个函数只执行一次,那全局函数会浪费性能,所以需要立即执行函数
立即执行函数特点
-
立即执行函数满足:
- 自动执行
- 执行完后立即销毁
(function () {}()); // W3C建议写法
(function () {})(); // 也能这样写
!function() {}(); // 这样也行
- 把函数变成表达式,后面加个括号(函数执行符号)才是完整的立即执行函数
- 这里函数外的括号就是把函数变成了表达式
- 立即执行函数前后必须确保有分号,否则会运算
// 立即执行函数小例子
(function () {
var a = 1,
b = 2;
console.log(a + b);
})(); // 3
// 可以保存立即执行函数的返回值
let num = (function (a, b) {
return a + b;
})(2, 4);
console.log(num);
//表达式才能被执行符号执行
(function test1() {
console.log(1); // 1
})();
let test2 = (function () {
console.log(2); // 2
})();
function test3(){
console.log(3); 报错
}();
function test(a, b) {
console.log(1);
}(6,5)
6, 5; // 函数不执行也不会被报错 括号里有东西JS就会认为是一个表达式而不是函数的执行符号
二、逗号操作符
例子
// 逗号表达式
let num = (2 - 1, 6 + 5);
console.log(num); // 11 num只返回逗号之后的表达式或值
面试题1
// 面试题 页面上会出现什么数字
function test() {
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function () {
// 每一次在给arr[i]赋值时只是把匿名函数放进去,但没有执行
document.write(i + "");
};
}
return arr; // 返回给外面的变量导致这10个匿名函数形成了10个闭包
}
var myArr = test(); // 此时test的AO和test切断但这10个匿名函数还抓着test的AO
for (var j = 0; j < 10; j++) {
myArr[j](); // 每一次执行时都会访问test的AO 此时的i就是10
}
// 打印10个10
面试1延伸
// 面试题延伸,如果想打印0-9
// 最常用的 让循环里的函数变成立即执行函数 每次执行的就是i
function test() {
for (var i = 0; i < 10; i++) {
(function () {
document.write(i + " ");
})(); // 页面上出现0-9
}
}
test();
面试题2
// 面试题2
var fn = (function test1() {
return 1;
},
function test2() {
return "2";
})();
console.log(typeof fn);
// 打印的是string 因为逗号运算符只返回逗号后的东西 函数fn只返回第二个test2的返回值 字符串2
面试题3
// 阿里面试题
var a = 10;
if (function b() {}) { // 函数声明不是false值 所以if能通过
a += typeof b; //因为if后面的括号让function b(){}变成表达式了,表达式内函数名没有意义,所以找不到b,所以b是undefined
}
console.log(a); // typeof 检查后返回的是字符串类型的undefined 所以10 + 'undefined' = '10undefined'
面试题4
// 有五个li 点击五个li打印其对应0-5的数字
let oLi = document.querySelectorAll("li");
for (var i = 0; i < oLi.length; i++) {
oLi[i].onclick = function () {
console.log(i);
};
}
//这样点击每一个li打印都是5 因为给每一个li循环赋值时只是绑定函数,当点击li才执行函数,执行函数时的i就等于5 所以每一次点击都等于5
//要达到预期效果
for (var i = 0; i < oLi.length; i++) {
(function (j) {
oLi[j].onclick = function () {
console.log(j);
};
})(i);
三、课后作业
作业1
// 累加器 0 写个闭包
// 执行一次函数 加1
let showAdd = document.querySelector("#showAdd");
let btnAdd = document.querySelector("#btnAdd");
let btnClear = document.querySelector("#btnClear");
let n = 0;
function render(num) {
showAdd.innerHTML = `当前数字是${num || 0}`;
}
render();
function add() {
n += 1;
return n;
}
btnAdd.addEventListener("click", () => {
render(add());
});
btnClear.addEventListener("click", () => {
n = 0;
render(n);
});
作业2
// 缓存器 一个班级,学生名字保存在数组里,两个方法写在函数中的一个对象中,第一个方法是加入班级,第二个方法是离开班级。
// 每次加入或离开,都需要打印新的学生名单
function gather(name) {
let className = [];
let operation = {
add: function (name) {
className.push(name);
console.log(className);
},
remove: function (name) {
let index = className.indexOf(name);
if (index < 0) {
console.log("删除失败,请确认删除名字是否存在 %o", className);
} else {
className.splice(index, 1);
console.log("删除成功 %o,", name, "已被删除", className);
}
},
};
return operation; //返回一个对象
}
let team = gather();
\