// 作用域和声明提前
// 函数作用域---> 局部变量
// 全局作用域---> 全局变量
// 实例一:变量只提前,声明不提前;函数提前声明和函数体;同名变量和函数,函数声明先提前
{
console.log(a);
a();
var a = 3;
function a() {
console.log(10);
};
console.log(a);
a = 6;
a();
}
// 闭包
// 一般情况下,作用域中的变量在利用完成之后/执行完毕后,浏览器的垃圾回收机制会自动寻找全局中未被引用的变量,对其进行垃圾回收,也就是说里面声明的变量会被释放。但闭包利用一个技巧,让作用域里面的变量,在函数执行之后依旧被保存没有被垃圾回收处理掉。
// 闭包实例1:
{
function foo(x) {
var tmp = 3;
return function(y) {
alert( x + y + (++tmp));
};
};
var bar = foo(2);
bar(10);
}
// 闭包实例2:
{
function a() { // 外部闭包域,一个名为 a 的 Function 对象
var p = 0; // 私有变量 p
var innerA = function() { // 内部闭包域,一个名为 innerA 的 Function 对象
console.log(p);
}
innerA(); // 1
P++; // 2
innerA();
};
a(); // undefined
}
// 闭包实例3:
{
function a() {
var n = 0;
function inc() {
n++;
console.log(n);
}
inc();
inc();
};
a();
}
// 闭包实例4:
{
function a() {
var n = 0;
this.inc = function() {
n++;
console.log(n);
}
};
var c = new a();
c.inc();
c.inc();
}
// 闭包实例5:
{
function a() {
var n = 0;
function inc() {
n++;
console.log(n);
}
return inc;
};
var c = a();
c();
c();
}
// 闭包实例6:
{
function fun(n, o) {
console.log(o);
return {
fun : function(m) {
return fun(m, n);
}
}
};
var a = fun(0).fun(1);
a.fun(1);
a.fun(2);
a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1);
c.fun(2);
c.fun(3);
}
/**
// 分析
// 实例1分析:
// 变量只提前,声明不提前;函数提前声明和函数体;同名变量和函数,函数声明先提前
function a() {
console.log(10);
};
var a
console.log(a); // 函数体f()
a(); // 10
a = 3;
console.log(a); // 3
a = 6;
a(); // a 已经被赋值为6,故会报错 a is not a function
// 闭包实例1分析:
{
function foo(x) {
var tmp = 3;
return function(y) {
alert( x + y + (++tmp));
};
};
var bar = foo(2);
bar(10); // 16
}
// foo(2) 调用时,此时x为2,tmp为3 被保存在当前foo函数的作用域当中,当把foo(2)赋值给bar时,相当于将return出的函数赋值给了bar,即bar等于return出的内部函数,故此时y=10 ,结果为16
// 闭包实例3分析:
// 调用a()时,由于函数体存在声明提前故
{
function a() {
function inc() {
n++;
console.log(n);
}
var n = 0;
inc(); // 1
inc(); // 2
};
a();
}
// 此时打印n时,内层函数没有n变量,会在外层函数找全局变量n=0,故第一次调用时 n = 1,以此类推
// 闭包实例4分析:
// 函数声明提前
{
function a() {
this.inc = function() {
n++;
console.log(n);
}
var n = 0;
};
var c = new a();
c.inc(); // 1
c.inc(); // 2
}
// 闭包实例5分析:
// 函数声明提前
{
function a() {
function inc() {
n++;
console.log(n);
}
var n = 0;
return inc;
};
var c = a();
c(); // 1
c(); // 2
}
// 闭包实例6分析:
{
function fun(n, o) {
console.log(o);
return {
fun : function(m) {
return fun(m, n);
}
}
};
var a = fun(0).fun(1); // undefined 0
a.fun(1); // 1
a.fun(2); // 1
a.fun(3); // 1
var b = fun(0).fun(1).fun(2).fun(3); // undefined 0 1 2
var b = fun(0).fun(1); // undefined 0
c.fun(2); // 1
c.fun(3); // 1
}
// a和c调用fun()时,相当于调用的是内部return的函数fun(m, n),此时,由于a,c已经被执行,n被赋值保存了起来,故n不随调用的变化而变化
*/