1. 变量提升
/*
EC(G) 创建全局作用域
变量提升:
var a;
var b;
var c;
test = 0x000; 作用域链[[scope]]:EC(G)
执行代码
*/
var a = 10,
b = 11,
c = 12;
function test(a) {
/*
EC(TEST) 函数作用域
作用域链<EC(TEST), EC(G)>
形参赋值:a = 10;当前上下文 a 私有
变量提升: var b; b私有的
*/
a = 1;
var b = 2;
c = 3; // c不是EC(TEST)私有的,向上级上下文EC(G)找
}
test(10); // 进test执行
console.log(a, b, c); // 10 11 3
2. 函数的arguments参数
- arguments的特点
- 在JS
非严格模式下,当初始化arguments和形参赋值完成后,会给两者建立一个映射机制,集合中的每一项和对应的形参变量绑定在一起,一个修改都会跟着修改,而且只会发生在代码执行之前建立这个机制 - 在JS
严格模式下,没有映射机制,也没有arguments.callee这个属性,箭头函数中没有arguments
- 在JS
/*
全局上下文EC(G)
变量提升
- var a;
- b = 0x000; [[scope]]: EC(G);
*/
var a = 4;
function b(x, y, a) {
/*
私有上下文EC(b)
初始化作用域链<EC(b), EC(G)>
初始化函数的this:window
初始化 arguments(实参集合,类数组):
{
0: 1, 1: 2, 2: 3,
length: 3,
callee: function b(){...}
}
形参赋值:x = 1 y = 2 a = 3 私有变量
变量提升:无
*/
console.log(a); // 3
arguments[2] = 10; // a=10
console.log(a); // 10
}
a = b(1, 2, 3); // 函数执行无返回值 undefined
console.log(a); // undefined
function fn(x, y, z) {
/*
arguments: {0: 10, 1: 20}
*/
x = 100;
console.log(arguments[0]); // 100
arguments[1] = 200;
console.log(y); // 200
z = 300;
console.log(arguments[2]) // undefined
}
function fn() {
// 存储的是当前函数本省,这样操作时为了方便递归调用
console.log(argument.callee)
}
fn();
3.匿名函数具名化
- 匿名函数具名化,只能在匿名函数中用这个名字
Array.prototype.unique = function unique() {};
console.log(unique) // Uncaught ReferenceError: unique is not defined
var b = 10;
(function b() {
// 匿名函数具名化之后,此时上下文中的b都是匿名函数本身(不允许修改)
b = 20;
console.log(b) // function b() {...}
})();
console.log(b) // 10
4.
/*
全局作用域EC(G)
变量提升
- var test;
*/
var test = (function (i) {
/*
自执行函数执行EC(any)
作用域链: <EC(any), EC(G)>
形参赋值: i= 2
变量提升:无
*/
return function() {
/*
test(5)执行 作用域 EC(test)
作用域链: <EC(test), EC(G)>
*/
alert(i *= 2)
} // return 0x001; [[scope]]:EC(any)
})(2);
test = 0x001;
test(5); // i = i*2 4
5.套娃
function fun(n, o) {
console.log(o);
return {
fun: function(m) {
return fun(m, n)
}
}
}
var c = fun(0).fun(1);
c.fun(2);
c.fun(3);
- 变量提升之后代码执行