还是理解不了闭包?

今天面试又跪在闭包上了,还是不能真正理解闭包。
看了阮一峰老师对闭包的理解并把思考题做完了,然后自己又加了难度,代码如下:

    var name   = "The Window";
    var object = {
        name       : "My Object",
        getNameFunc: function () {
            return function () {
                return this.name;
            }
        }

    };
    var obj    = {
        name   : 'wgm',
        sayName: function (callback) {
            callback();
        }
    }

    console.log(
        obj.sayName(object.getNameFunc())//undefined
    );

为什么打印出来的是undefined

阅读 1.8k
2 个回答

整个闭包没有什么问题,在

return function () {
  return this.name;
}

这一闭包函数里获取到的this确实是window,你可以在这一层打印就知道。
相反是有一个比较简单的地方楼主漏掉了,清楚来说console的内容是obj.sayName(...)的返回值,但是这个函数有返回值么?

sayName: function (callback) {
  callback();
}

callback()执行完return回的数据,没有变量来接受也没有被sayName函数返回,所以结果才是undefined,如果想得到正确的结果,楼主可以稍微修改一下成return callback();就可以了。

另外再简单解释一些闭包相关的一些概念,希望能助你加深对闭包理解。
JS的链式作用域特点就是,函数执行是从外往内进入,而从内往外返回,所以内层函数执行时可以获取到外层函数里定义的变量,但是外层函数返回的时候内层函数执行完毕已经在内存中销毁了,所以无法获取到内层函数作用域定义的变量,也就是变量无法向下层获取。那外层函数有时候需要获取内层函数的变量该怎办?于是闭包出现了,为了解决无法从内部函数获取变量的问题,在内层函数里再定义一个函数来获取它的变量返回给外层函数,有点像挖一新坑填一个老坑的意思,比如下面的代码:

function a () {
  var aa = 'aa', cc;
  function b () {
    var bb = 'bb'
    return function c () {
      return bb
    }()
  }
  cc = b()
  console.log(cc)
}
a()

如果没有c函数,a函数就无法获取到b函数里的bb。所以闭包的使用是为了拿到内层函数的变量才存在的,没有这种需求的时候就不用使用闭包。

return this.name;
这里的this 指向函数 return function () {} 而不是你期望的object,所以此时this.name就是undefined.
这样:
 var object = {
    name: "My Object",
    getNameFunc: function () {
        return function () {
            return object.name;
        }
    }
};
当然结果还会是undefined,但是这个问题就是闭包的问题了。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题