问答

关于闭包的一些提问

作者:admin 2021-04-18 我要评论

之前看到一段代码,作者提了一个问题:代码中f引用了变量d,同时f被外部变量a引用,所以形成闭包,导致变量d滞留在内存中。那么变量c是否也滞留在内存中呢? var...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

之前看到一段代码,作者提了一个问题:代码中f引用了变量d,同时f被外部变量a引用,所以形成闭包,导致变量d滞留在内存中。那么变量c是否也滞留在内存中呢?

var a
function b() {
  var c = new String('1')
  var d = new String('2')
  function e() {
    console.log(c)
  }
  function f() {
    console.log(d)
  }
  return f
}
a = b()

我执行代码查阅[[Scopes]]发现 c 变量确实滞留在闭包内,这是因为函数内闭包共享。那么我有个疑惑,为何变量 c滞留在缓存中,而函数 e 会被回收??了呢?
image.png

再如我把代码改一改:

var kk = 'hello'
function b() {
  var c = new String('1')
  var d = new String('2')
  function e() {
    console.log(c)
  }
  function f() {
    console.log(kk)
  }
  return f
}
var  a = b()
console.dir(a)

此时再去打印 a 得出:
image.png

迷惑了,这为啥又变成c 滞留呢,d去哪了?还有这个 f 函数为啥没成为闭包呢?是不是说明了 成为闭包的条件是内部函数必须跟外部函数关联,而跟全局变量关联的时候并不能成为闭包呢?

还有一个提问:为什么 getName中的内部函数打印出来的 this 指向 window 呢?

var object = {
     name: "object",
     getName: function() {
        console.log(this,'000000')
        return function() {
             console.info(this,'1111')
        }
    }
}
var a = object.getName()
console.log(a) //指向 object 对象
var b = a()
console.log(b) //指向全局的 window

暂时还没能总结陈词,看了一篇帖子对我提出的函数调用解释是这样子的??,(不知道得出来的总结对不对,下面是我的理解,如果有异议那就戳我并且给点纠正方案给我吧~~Thanks?(?ω?)?):
https://zhuanlan.zhihu.com/p/...

  • js 中的函数调用形式:
func(p1, p2) 
obj.child.method(p1, p2)
func.call(context, p1, p2)

所以getName中的内部函数打印出来的 this 指向 window
obj.child.method.call(obj)

ok,加深难度,回答一下下面的这个函数调用解析情况:

function test (){
    console.log(this,'000000')
    var obj = {
    a:function (){
       console.log(this,'1111')
       return function(){
            console.log(this,'22222')
        }
    }
    }

return obj
}

test().a()()
//打印结果
// window{...},00000
// {a:f}, 11111
// window{...},22222

同样根据上面得出的解析是:
fn.call(obj).child.method.call(obj,afunction).call(undefind)
所以最里面的函数调出出来指向的 this 是指向 window,那么如果我们想在最内部的函数能够获取到上面的 obj 中的变量,方法等内容时可以这么写:

function test (){
    console.log(this,'000000')
    var obj = {
    a:function (){
       console.log(this,'1111')
        var that = this
       return function(){
            console.log(that,'22222')
        }
    }
    }

return obj
}

test().a()()

//{a:f}, 11111
//{a:f}, 22222

得出结论:(结论有点粗糙,在总结更加官方的解释中。。。欢迎贴出您的总结陈词)
this的指向完全取决于函数调用的位置,a 函数调用时,他的调用位置是 obj.child.method.call(obj)的调用方式,而最内层的函数调用时,因上方的 a 函数已经调用完毕,函数不通过对象调用时,this就指向window

###

b函数运行完成,执行上下文就出栈了,但是由于其变量对象被外部引用,所以变量对象还是存在的,所以还能继续访问b函数里面的对象。

他回收不是说只留一个或几个属性,你这里打印的结果只代表chrome浏览器控制台的机制,和v8无关,其他浏览器应该也各有不同,比如firefox

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • nginx响应速度很慢

    nginx响应速度很慢

  • 点击选中的多选框,会在已选那一栏显示

    点击选中的多选框,会在已选那一栏显示

  • PHP 多态的理解

    PHP 多态的理解

  • 关于C语言中static的问题

    关于C语言中static的问题

腾讯云代理商
海外云服务器