普通的函数在全局定义之后是存在GO中的,是不释放的,在想调用的时候就能调用 有些函数只需要运
行一次之后再也不会执行 -> 立即执行函数
(1)立即执行函数 (初始化函数)
IIFE -> immediately-invoked function expression D2262 G7085
- 自动执行- 执行完自己销毁
///
//写法一:
(function () {
})()
//写法二
(function(){
}());
闭包demo
function test() {
var arr = [];
for(var i =0;i<10;i++){
arr[i] = function(){
document.write(i +' ');
}
}
return arr; //返回arr数组时 i等于10 每次function(){} 赋值给arr[i] 但是未赋值
}
var myArr = test();
// console.log(myArr);
for(var j = 0;j<10;j++){
myArr[j]();
}
//输出10个10
解决方案一 立即执行函数
function test() {
// var arr = [];
for(var i =0;i<10;i++){
(function(){
document.write(i +' ');
}());
}
}
test();
解决方案二 改变传参
function test() {
var arr = [];
for(var i =0;i<10;i++){
arr[i]=function(num){
document.write((num) +' ');
}
}
return arr;
}
var myArr = test();
// console.log(myArr);
for(var j = 0;j<10;j++){
myArr[j](j);
}
解决方案三 立即执行并传参
function test(){
var arr = [];
for(var i = 0;i < 10;i++){
(function(j){
arr[i]=function(){
document.write(j +' ')
}
})(i);
}
return arr; //返回arr数组时 i等于10 每次function(){} 赋值给arr[i] 但是未赋值
}
var myArr = test();
for(var j = 0;j<10;j++){
myArr[j]();
}
demo2
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</body>
<script>
var oLi = document.querySelectorAll('li');
for (var i = 0; i < oLi.length; i++) {
oLi[i].onclick = function () {
console.log(i);
}
}
</script>
demo3
var fn = (
function test1(){
return 1;
},
function test2(){
return '2';
}
)();
console.log(typeof(fn)); //stirng
demo4
var a =10;
if(function b(){}){ //()括号的作用:加括号里的内容转换成表达式 表达式忽略函数名 => function (){} =>undefined
a+=typeof(b);
}
console.log(a); // 10undefined
课后作业
闭包写法
1.累加器
// 单独返回数组写法
function fnx(){
var num = 0;
function add(){
num++;
// console.log('运行加法运算'+num);
return num;
}
function sub(){
num--;
// console.log('运行减法运算'+num);
return num;
}
return [add,sub];
}
var arr = fnx();
console.log(arr[0]());
console.log(arr[0]());
console.log(arr[1]());
console.log(arr[0]());
//整体返回数组写法
function fnx2(){
var num = 0;
var optarr = [
function add(){
num++;
console.log(num);
},
function sub(){
num--;
console.log(num);
}
]
return optarr;
}
var arr2 = fnx2();
arr2[0](10);
arr2[1](10);
// 整体返回对象写法
function fn3(){
var num = 0;
var optobj = {
add: function () {
num++;
console.log(num);
// return num;
},
sub:function (){
num--;
console.log(num);
// return num;
}
}
return optobj;
}
var obj = fn3();
obj.add();
obj.sub();
//单独返回对象写法
function fn4(){
var num = 0;
function add(){
num++;
console.log(num);
};
function sub(){
num--;
console.log(num);
};
return {add,sub};
}
var obj2 = fn4();
obj2.add();
obj2.sub();
2. 一个班级,学生名字保存在一个数组里,两个方法写在函数中的一个对象中,第一个方法加入班级,第二个方法离开班级,每次加入或离开
//都需要打印新的学生名单
//数组写法
function fnstudent(){
var name = [];
var stuopt = [
function add(newname) {
name.push(newname);
console.log(name);
},
function sub(newname) {
var index = name.indexOf(newname);
console.log(index);
if(index>-1){
name.splice(index,1);
}
console.log(name);
}
]
return stuopt;
}
var objstudent = fnstudent();
objstudent[0]('ming');
objstudent[0]('xyf');
objstudent[1]('ming');
//对象写法
function fnstudent2(){
var name = [];
var stuopt = {
add:function(newname) {
name.push(newname);
console.log(name);
},
sub: function(newname) {
var index = name.indexOf(newname);
console.log(index);
if(index>-1){
name.splice(index,1);
}
console.log(name);
}
}
return stuopt;
}
var objstudent = fnstudent2();
objstudent.add('ming');
objstudent.add('xyf');
objstudent.sub('xyf');
遍历查找的写法
function fnstudent2(){
var name = [];
var stuopt = {
add:function(newname) {
name.push(newname);
console.log(name);
},
sub: function(newname) {
for(var i=0;i<name.length;i++){
var item = name[i];
if(item === name){
students.splice(i,1);
}
}
console.log(name);
}
}
return stuopt;
}
var objstudent = fnstudent2();
objstudent.add('ming');
objstudent.add('xyf');
objstudent.sub('xyf');
