alert()也算一次运算
老样子,举例说明
例1:
/*
* EC(G)变量提升
* var a;function b(){} =>0x0000 [[scope]]:EC(G)
*/
var a = 1;
function b(c){
/*
*EC(b)
* 作用域链:<EC(b),EC(G)>
* 形参赋值:c = 2【c是私有变量】
* 变量提升:--
*/
alert(c+a++);//3
//++在变量后边,那么先算其他运算,在算++,由于alert也算一次运算,所以弹出c+a,2+1=3,
然后在算a++,那此时alert已经弹完了,所以a++只是在系统中运算,不会表现出来
};
b(2);
console.log(a);//这是输出a,已经是a++运算之后的结果了,所以是2
匿名函数具名化
例2:
/!*
* EC(G)变量提升
* var b;
* 自调函数不进行变量提升,执行时候直接创建堆和执行上下文
*!/
var b = 10;
(function b() {
/!*
* 自执行函数本身应该是匿名函数(还有函数表达式或者回调函数等都是匿名),只不过为了
* 保证良好编码习惯,我们经常给本应是匿名的函数 “具名化”(起个名字)
* 1.这个名字只能在函数内部被调用,函数外面用不了(可以理解为是私有变量)
* 2.这个名字的变量,在函数内部,值也是不能被修改的(改了也没用,还是代表函数)
* EC(AN)
*!/
b = 20;
console.log(b); //=>函数本身
})();
console.log(b); //=>10
(function AAA() {
// console.log(AAA); //=>函数本身(这样后期在递归调用的时候,可以直接基于AAA执行
即可,无需再使用arguments.callee了【arguments.callee在严格模式下不支持】)
AAA = 1000;
console.log(AAA); //=>函数本身
})();
console.log(AAA); //=>Uncaught ReferenceError: AAA is not defined
例3:
(function AAA() {
/!*
* 如果是基于VAR/LET/FUNCTION等再次声明的操作单独处理,会把这个具名化的名字改为正常
* 的私有变量,也就是名字不再代表函数了
*!/
// console.log(AAA); //=>Uncaught ReferenceError: Cannot access 'AAA' before initialization
let AAA = 100;
console.log(AAA); //=>100
})();
/* (function AAA() {
console.log(AAA); //=>函数(输出1的)
function AAA(){console.log(1)}
console.log(AAA); //=>函数(输出1的)
})(); */
/* (function AAA() {
console.log(AAA); //=>undefined
var AAA = 200;
console.log(AAA); //=>200
})(); */
函数形参带ES6默认值,函数体中重复声明会多形成一个块级作用域
-
函数执行的时候,如果设置了形参变量(“并且”部分形参变量设置了ES6中的形参赋值默认值),这样在形成私有上下文的时候,会多创建一个块级上下文(函数的大括号单独看做一个块级上下文)
-
第二个限制条件是:当前形参变量在大括号中被重新声明过
例4: /!* * EC(G)中的变量提升 * var x; * function func(x,y){...} =>func=AAAFFF000 *!/ var x = 1; function func(x, y = function anonymous1() {x = 2}) { /!* * EC(FUNC)私有上下文 * 形参赋值:x=5 y=BBBFFF000(anonymous1匿名函数) [[scope]]:EC(FUNC) * 变量提升:由于形参带ES6默认值,此时函数体内重新声明了形参,所以会形成一个块级作用域 * EC(BLOCK)块级作用域 * 形参赋值:-- * 变量提升:会把EC(FUNC)私有上下文的形参赋值拷贝一份到这里 *!/ var x = 3; var y = function anonymous2() {x = 4}; //此时块级作用域中的x、y与私有上下文的形参x、y是分开的,自己是自己的 y(); //=>Y执行是让ANONYMIOUS2执行,里面的x = 4是块级作用域中的x console.log(x); //=> 4 } func(5); console.log(x); //=>1