闭包
闭包: 从现象上来说,就是能访问别的函数内部变量的函数叫做闭包。从原理上来说,在一个函数中通过return抛出一个子函数,当子函数在外层用变量接收后,该子函数就不被销毁,从而产生的一种作用域链不释放的现象。
立即执行函数: 函数自动执行,执行完成以后立即释放。也叫初始化函数。英文名称是,IIFE - immediately-invoked function expression 立即执行的函数表达式。
立即执行函数的两种基本写法:
1. 写法1:最常用写法:写到括号外。
(function(){ //语句 })()。
2. 写法2:W3C推荐写法:写到括号内。
(function(){
var a = 1,
b = 2;
return a + b;
}()); //W3C建议
3. 写法3:函数表达式写法可执行。
var test = function (){console.info('exec')}(); //紧跟执行符号
4. 写法4:将函数变成表达式后执行;
+ function(){}();
括号和运算符转换表达式:括号括起来的都是表达式,里面是函数也好,数字计算也好。 表达式才能被执行符号执行,括号里面包裹的不管是什么东西,都是表达式。
函数变成表达式后的特点:它的函数名会被忽略掉,相当于匿名函数;
把函数声明变成函数表达式的符号: +。 -。 !。=。 1&&。 0|| 。例:+function test(){}
逗号运算符: 返回所有逗号最右边的值。如var a = (4, 6, 5)返回的是5。
做js题目的阅读顺序:1. 找变量声明,找函数声明。2. 逐条执行和分析。
对象属性的增删改查:增改obj.property = 1。查obj.property。删除对象的属性的两种方法:1. delete obj.property。2. obj.property = undefined。
测试题:
1. 报错吗?
function test(a){
}(a);
//不报错
//原因是js引擎把 (a) 括号里面看做一个表达式,而非立即执行符号。
//前面是函数声明,后面是个表达式(a),不报错。
2. 结果是什么?并解释这种现象。
function test() {
var arr = [];
//var i = 0; //要把for循环的i拿出来放到外边, 直观
for(var i = 0; i < 10; i++){
arr[i] = function(){
document.write(i + " ");
}
//i++, 自加放到for循环最后, 直观
}
return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++){
myArr[j]();
}
// 10个10
// 数组的每一项保存的i,都是同个上层的i,i的值是10,然后打印了10次。
3. 修改上一题,让它能够打印0到9。
function test() {
var arr = [];
for(var i = 0; i < 10; i++){
(function(j){
arr[j] = function(){
document.write(j + " ");
}
})(i); //加立即执行,把i变成局部变量。
}
return arr;
}
var myArr = test();
for(var j = 0; j < 10; j++){
myArr[j]();
}
//最常用的闭包解决方案:加立即执行函数;
4. 打印什么?解释原因。
var a =10;
if(function b(){}){
a += typeof(b);
}
console.log(a);
// '10undefined'
// 括号内是函数表达式,表达式是忽略函数名的
// 注意判断条件的函数名字,细心。
5. 输出结果:
var fn = (
function test1(){
return 1;
},
function test2(){
return '2';
}
)();
console.info(fn); // '2'
var num = (1, 2);
console.log(num); // 2
//逗号运算符题目