V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
sivacohan
V2EX  ›  JavaScript

我这样写算闭包吗?

  •  
  •   sivacohan · 2013-06-28 23:42:42 +08:00 · 3407 次点击
    这是一个创建于 4172 天前的主题,其中的信息可能已经有所发展或是发生改变。
    https://gist.github.com/SIvaCoHan/5885663/

    问题是,我function obj 没有var xxx这种,不过按照逻辑,我这个也算保留上下文了。算闭包?

    PS: 改了好几次,也没能把gist贴出来
    17 条回复    1970-01-01 08:00:00 +08:00
    binux
        1
    binux  
       2013-06-28 23:44:08 +08:00   ❤️ 1
    heroicYang
        2
    heroicYang  
       2013-06-28 23:45:56 +08:00 via iPhone   ❤️ 1
    算的。
    darasion
        3
    darasion  
       2013-06-28 23:51:29 +08:00
    贴gist貌似不能用httpS
    switch
        4
    switch  
       2013-06-28 23:52:24 +08:00 via Android
    不要为了闭包而闭包,在 ECMAScript 5 里就没有专门描述这个的。
    sivacohan
        5
    sivacohan  
    OP
       2013-06-28 23:52:41 +08:00
    @binux
    @heroicYang
    谢谢!还有一个问题。在js中使用new关键字来创建对象。
    给class添加方法或者要继承某个class的时候通常采用什么方法呢?
    猫头鹰那本给我弄迷糊了。
    Mutoo
        6
    Mutoo  
       2013-06-28 23:53:59 +08:00   ❤️ 1
    算的,可以看看这个例子

    http://gist.github.com/mutoo/5780122
    sivacohan
        7
    sivacohan  
    OP
       2013-06-28 23:54:38 +08:00
    @switch 这个地方用闭包有两个原因,一个是命名空间,js太多了。另外一个是我希望能通过
    var abc = obj('xxx') 这种形式获得一个对象。页面上会有几个obj对象。
    在这我究竟到底是这么写,还是用new来完成。本能的不喜欢js的new
    Mutoo
        8
    Mutoo  
       2013-06-28 23:55:42 +08:00   ❤️ 1
    @sivacohan 关于javascript类继承,有一篇很有名的文章,请参见 http://ejohn.org/blog/simple-javascript-inheritance/
    Mutoo
        9
    Mutoo  
       2013-06-28 23:57:10 +08:00   ❤️ 1
    @sivacohan 另外如果你用js的使用class的方式不太理解,推荐你看看 《javascript 设计模式》前几章;
    oldcai
        10
    oldcai  
       2013-06-28 23:59:22 +08:00
    @darasion 可以。
    Golevka
        11
    Golevka  
       2013-06-29 13:59:09 +08:00
    @switch ECMAScript 5中明确说明了什么是Lexical Environment, 并且13.2: Creating Function Objects中也明确说明创建一个函数对象需要"a Lexical Environment specified by Scope", 这不就是你们喜闻乐见的闭包么?
    switch
        12
    switch  
       2013-06-29 15:02:19 +08:00
    @Golevka 就是没有明确定义“闭包”这个词。所以说与其去抓这个词还不如去理解 Lexical Environment 了(话说从这个词的字面意思上也不好理解)。
    Golevka
        13
    Golevka  
       2013-06-29 15:12:12 +08:00
    @switch 我倒是感觉理解了词法作用域再去理解闭包就很清晰了, 其实闭包的最简单实现方法就是把lambda和当前env绑定在一起求值成一个closure (ECMAScript中也是这么描述的).
    switch
        14
    switch  
       2013-06-29 15:21:15 +08:00
    @Golevka +1, 我不太喜欢在 js 里提闭包这个概念。
    heroicYang
        15
    heroicYang  
       2013-06-30 10:02:09 +08:00
    @sivacohan 用模拟类继承和原型式继承都是可以的~
    DaniloSam
        16
    DaniloSam  
       2013-06-30 12:15:30 +08:00
    闭包: 红宝书第二版145页(抱歉我买的时候没有第三版), 理解作用域链和lambda表达式就理解了闭包了

    new是个啥东西, 想生成对象想继承咋办?

    可以参看jQuery的构造函数: https://github.com/jquery/jquery/blob/master/src/core.js
    #41, #81

    new出来的对象, 有一个隐藏的__proto__指向原对象的prototype, IE之外的浏览器可以直接访问到, 原对象的prototype上定义的函数, 可以直接调用. 可以理解为new出来的对象, 是原对象的一个实例, 通过__proto__这个属性, 与原对象的原型链建立了链接, 当调用函数的时候, 会对原型链进行查找, 进而访问原型链上的函数

    猫头鹰#29写的很清楚了, 可以写几行代码试一下

    闭包本质是对作用域链的理解, 不要为了闭包而闭包
    DaniloSam
        17
    DaniloSam  
       2013-06-30 12:24:38 +08:00
    补充一下:
    var Foo = function(){
    return "Foo init...";
    }
    Foo.prototype.say = function(){
    console.log('hello world');
    }
    var bar = new Foo()
    , baz = Foo();
    bar.say();
    baz.say();

    运行结果显而易见, bar.say 通过原型链可以查找到, 所以能打印出'hello world'
    baz实质上是Foo 构造函数调用的返回值, 在这里指定了返回值, 那就是'Foo init...', 未指定, 则为undefined
    此为用了new 和没用new 的区别
    所以如果想"造"出一个实例, 别忘了 new , 或者直接在构造函数内返回一个实例, 如jQuery的处理方式, 或参考红宝书#131 对继承和原型链的详细解释
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2827 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 07:32 · PVG 15:32 · LAX 23:32 · JFK 02:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.