给大家出一道关于JS闭包和赋值的题,希望大家分析一下?

第一部分

案例一

var num=1;
function f(){
  
  return function(){
  
    num++;
    console.log(num);
  };
}
var c=f();
c();
c();
var d=f();
d();
d();
console.log(c===d);

结果是:

console:
2
3
4
5
false

案例二

function f(){
  var num=1;
  return function(){
  
    num++;
    console.log(num);
  };
}
var c=f();
c();
c();
var d=f();
d();
d();
console.log(c===d);

结果是:

Console 
2
3
2
3
false

案例三

function f(){
  
  return function(){
    var num=1;
    num++;
    console.log(num);
  };
}
var c=f();
c();
c();
var d=f();
d();
d();
console.log(c===d);

结果:

console
2
2
2
2
false 

第二部分

案例一

 var num={a:1};
function f(){
  
  return function(){
   
    num.a=2;
    return num;
  };
}
var c=f()();
console.log(c);


var d=f()();
console.log(d);

c.a=5;
console.log(c);
console.log(d);


console.log(c===d); 

结果:

console
[object Object] {
  a: 2
}
[object Object] {
  a: 2
}
[object Object] {
  a: 5
}
[object Object] {
  a: 5
}
true  

案例二

function f(){
  var num={a:1};
  return function(){
   
    num.a=2;
    return num;
  };
}
var c=f()();
console.log(c);


var d=f()();
console.log(d);

c.a=5;
console.log(c);
console.log(d);

console.log(c===d);

结果:

console
[object Object] {
  a: 2
}
[object Object] {
  a: 2
}
[object Object] {
  a: 5
}
[object Object] {
  a: 2
}
false

案例三

function f(){
  
  return function(){
    var num={a:1};
    num.a=2;
    return num;
  };
}
var c=f()();
console.log(c);


var d=f()();
console.log(d);

c.a=5;
console.log(c);
console.log(d);

console.log(c===d);

结果:

console
[object Object] {
  a: 2
}
[object Object] {
  a: 2
}
[object Object] {
  a: 5
}
[object Object] {
  a: 2
}
false  

  • 请留意console.log的值。

  • 请留意在第一部分我只是改变了var num=1出现的位置以造成不同的闭包情况,同样第二部分我只是改变了var
    num={a:1}出现的位置以造成不同情况的闭包。

  • 到底什么情况下c和d才会是===? c和d相等实际是什么?词法环境还是什么相等?

  • 各个console值出现的原因? 请具体些分析,不妨从js代码解析、闭包等深层次的原因分析


等你来挑战!!!

阅读 4.1k
4 个回答

回答下第一部分,其余部分道理一样。
知识点: 变量作用域 作用域链 引用类型
案例一:num属于全局变量,所有的num变量均是这一个值。所以每次num++,便会修改num的值。至于c === d 这是两个不同的函数,所在内存的引用不同自然也就是false。
案例二: num放在了函数内部,函数返回的匿名函数便形成了闭包,上面提过c 与 d 代表的是两个不同的函数,各自有各自的num变量,当外部函数f()执行完毕后,由于内部闭包的存在,该变量并不会被释放。所以num会被累加。
案例三: num处于f()返回的匿名函数内部,没有产生闭包,该函数调用完毕后会被释放。

函数每次执行的上下文都是不一样的,但是如果返回值引用的是全局作用域的对象,那么这个对象是一样的。你只需要搞清楚返回值或函数里引用的对象的作用域就可以了。

作用域,作用域链。

http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain.html

关于作用域,js是只有词法作用域没有动态作用域。所以调用函数的时候,先去函数声明或表达式定义时的作用域中寻找变量(这里当然可能涉及到提升的问题,你没问就当你懂了),如果找到该变量就取出该变量的值(这是一个RHS)无法获取该变量时,会跳出作用域到嵌套作用域的上一层寻找,直到找到全局作用域。
再补充一句吧:变量仅仅是存放值的容器,希望你能理解。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题