跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 闭包和对象的区别?
未分類
12 1 月 2021

闭包和对象的区别?

闭包和对象的区别?

資深大佬 : asanelder 0

在看 js 的闭包, 感觉和面向对象中的对象差不多啊

闭包: 行为以及数据的绑定
对象: 行为以及数据的绑定

感觉没差啊, 是不是可以使用对象来代替闭包?

大佬有話說 (44)

  • 資深大佬 : ConradG

    本来俩就是一个东西——方法执行上下文

  • 資深大佬 : fpure

    闭包是穷人的对象,对象是穷人的闭包
    你可以用闭包来模拟对象,或者用对象来模拟闭包,除非有必要的话

  • 主 資深大佬 : asanelder

    @ConradG #1
    @fpure #2

    是啊, 记得之前看过很多讲这个的文章, 感觉说的很不明觉厉, 今天又仔细看了一下,感觉和对象差不多.

    什么保存上下文环境, 驻留在内存中, 这不就是对象么.

  • 主 資深大佬 : asanelder

    同一个东西, 使用闭包和对象来实现, 感觉也差不多.

    “`javascript
    function createIncrementor(start) {
    return function () {
    return start++;
    };
    }

    var inc = createIncrementor(5);

    inc() // 5
    inc() // 6
    inc() // 7
    “`

    “`java
    class Incrementor {
    private int start;

    Incrementor(int start) {
    this.start = start;
    }

    int inc() {
    start++;
    }

    }
    “`

  • 資深大佬 : codehz

    是这样的,你可以
    function Class() {
    let x = 1;
    let y = 2;
    return function(action, params) {
    switch(action) {
    case “get-x”: return x; break;
    case “set-x”: x = params[0]; break;
    case “get-y”: return y; break;
    case “set-y”: y = params[0]; break;
    default: throw new Error(“not implemented”);
    }
    }
    }
    然后
    let instance = Class()
    console.log(instance(“get-x”)); // 1
    instance(“set-x”, [5]);
    console.log(instance(“get-x”)); // 5
    顺带提示,这种方法还可以实现继承,多态等其他面向对象特性

  • 資深大佬 : fpure

    别想的太复杂,闭包就是用来解决返回一个函数之后的上下文问题,而对象就是通常用来组织数据的结构;本质都是存储状态;不用把他们想的太神秘,用的时候你自然就知道该用闭包还是对象了

  • 主 資深大佬 : asanelder

    @fpure #6 嗯嗯, 主要是网上说的太高大上了, 之前心里有些害怕, 哈哈

  • 資深大佬 : codehz

    对象代替闭包,在某些没有闭包的语言里也是可行的(前面看反了(
    甚至没有类这种机制的情况下都是可行的方案
    主要方法就是将局部变量变成对象属性,或者结构体属性
    然后作为一个环境参数在多个普通函数之间传递即可
    ( c 库主流的设置回调函数要给一个 void*作为用户指针就是这样来的)

  • 資深大佬 : OxOzZ

    SICP 第二章

  • 資深大佬 : SuperMild

    话不能这么说,

    自行车:代步工具
    小轿车:代步工具

    光看定义是感觉没差,但能不能相互代替?

    一个比较轻,一个比较重;一个适用于简单(短距离)场境,一个适用于复杂(远距离)场境;一个结构简单,一个结构复杂。

  • 資深大佬 : ngn999

    《代码的未来》里说: 对象与闭包是同一事物的正反两面.

    https://www.cnblogs.com/edisonchou/p/4873315.html

  • 資深大佬 : ianva

    真该看看 SICP,原本很简单的世界就是因为面向对象这一个抽象把东西都搞复杂了,java 缺少这种函数是一等公民这种最基本的规则

  • 資深大佬 : ianva

    从面向对象的语言入门编程真会有很多偏见,SICP 选的 Scheme 这种精简到不能再精简的语言才能呈现编程的最原本的东西

  • 資深大佬 : ianva

    可以看看王垠实现解释器的这篇文章 http://www.yinwang.org/blog-cn/2012/08/01/interpreter,里面有实现关于闭包的部分,还是很容易看清楚的

  • 主 資深大佬 : asanelder

    @ianva #14
    @ianva #13
    @ianva #12

    嗯, 将来一定要好好拜读一下 SICP

  • 資深大佬 : Leviathann

    闭包是穷人的对象
    对象是穷人的闭包

  • 資深大佬 : faceRollingKB

    es6 出现以前,js 没有私有属性 /方法的概念,这才有了闭包,利用作用域来实现私有

  • 主 資深大佬 : asanelder

    @faceRollingKB #17 是不是 es6 出现后, 之前使用闭包的场景就大大减少了啊

  • 資深大佬 : ianva

    所有函数式编程的场景都是靠闭包过的,这也是 JavaScript 最有用的特性了,举个例子 https://ramdajs.com/
    特别是 es6 之后有箭头函数了,应用的就越来越广泛了

  • 資深大佬 : Cbdy

    @asanelder 不是

  • 資深大佬 : xiangbohua

    我的理解中,闭包有两层含义:
    一种是闭包的直接定义。
    一种是实际编码中定义的函数。
    我们通常说某种语言是否支持闭包的时候,我们用的第一层含义,当我们写出一个匿名函数用到闭包特性的时候,我们可以说我们写了一个闭包。
    实际上,支持闭包的编程语言通常都支持、将一个方法或者函数当成参数传递,C#的委托、JS 的会调函数、Java 里面的匿名代码块等等。
    我们经常会说到,函数或者方法能够跻身为某种语言里面一等公民的时候,通常也就支持闭包,那么此时我们定义的 C#的委托、JS 的会调函数、Java 里面的匿名代码块都已经是一个对象了。
    所以:
    我觉得,当我们说闭包是什么的时候,我们说的是一种定义,当我们讨论某个具体代码的时候我们讨论的是一个对象,只不过这个对象具有闭包特性。
    以上
    如果不正确请指正哈

  • 資深大佬 : xiangbohua

    @ianva Java 现在已经有了额

  • 資深大佬 : darknoll

    什么叫差不多?闭包是函数式编程及其核心思想“Lambda 计算法”( Lambda Calculus )的必备基本设定。js 不是面向对象的语言,好好看看函数式编程吧,别整天把啥东西都往面向对象那一套上边靠。

  • 資深大佬 : billlee

    C++03 就是用类来代替闭包的

  • 資深大佬 : nthhdy

    @darknoll lambda calculus 里面没有闭包的概念吧。闭包是在 scheme 语言里最初实现的,就是为了做到为 free variable 求值时到函数定义的环境中去找值,而不是到函数调用的环境里找。早期的 lisp 实现就是到函数调用环境里找的,据说 emacs lisp 到现在都是,导致写出来的代码非常反直觉。lambda calculus 里只有 application 和 abstraction,都没有现代编程语言里的“变量”这种东西。

  • 主 資深大佬 : asanelder

    @xiangbohua #21 铁子的解释可以

  • 資深大佬 : walpurgis

    闭包写习惯了根本懒得用 es6 class 语法,毕竟函数都作为变量满天飞了,函数返回函数再正常不过的事情了

  • 資深大佬 : ghostheaven

    对象:带方法的数据
    闭包:带数据的方法

  • 資深大佬 : ruyu

    在一些语言中, 方法只是第一个参数是 this/self 的函数. 但闭包不是, 闭包是自带状态的.

  • 資深大佬 : gtx990

    fp 爱好者也别啥都往 fp 上靠

  • 資深大佬 : secondwtq

    “fp 爱好者“表示,可以去看一下 TAPL 的 “Imperative Objects” 这一章,这一章使用带简单 subtyping 以及 records,references,fix 操作符等基本扩展的 lambda calculus 对“面向对象”的基本行为进行了“approximation”。
    我看的时候总有一种初学 JavaScript 的逮虾户 …
    但是最后最 tricky 的是 open recursion 的模拟(作者将 open recursion 归为 OOP 的“fundamental features”之一),这个是以前看 JS 教程的时候没有意识到的——这东西在大多数非 FP 语言里面几乎是天经地义的事情,我也 take it for granted 了 …

  • 資深大佬 : FrankHB

    @nthhdy 你自己都说 free variable 了,这不是变量是什么。
    LC 的变量和现代编程语言中的一般意义上的变量(c.f. IEC 2382) 本来就是一回事,无非是默认共享命名空间无视作用域规则。把变量曲解为可变状态是历史上出现得晚得多的脑补,到现在仍然是片面的(按这说法纯 FP 语言里就没变量了)。
    @secondwtq 实现所谓的 open recursion 不需要 OOP 。
    名称解析直接整个 late binding 就行。不少动态语言的函数体里就是这样做的,函数定义时不管,拖到调用时才确定自然就 open 了,缺的只是没给在对象语言构造捕获环境(能够让你引用 this 这样的东西)的方法罢了。

  • 資深大佬 : darknoll

    就说了些上学学过的东西就变成了 fp 爱好者,真棒

  • 資深大佬 : faceRollingKB

    @asanelder 有了 class 以及 module,闭包基本就不需要了,但实践中还是会偶尔用用,使用场景还是有的

  • 資深大佬 : user8341

    @faceRollingKB
    es6 怎么定义私有属性?

  • 資深大佬 : looking0truth

    @user8341 es2020,变量名前加#号

  • 資深大佬 : yaphets666

    @walpurgis 日常哪里会用到闭包呢? 不是库里头应用的 是自己写代码的时候 实现什么功能会用到闭包呢?

  • 資深大佬 : user8341

    @looking0truth 嗯。es2020 是 es11 了,不是 es6 。这么说 es6 应该是没有此功能的。

  • 資深大佬 : brust

    czq?

  • 資深大佬 : faceRollingKB

    @user8341 好吧,平时太依赖 ts 、babel 了,没注意这个问题,my bad

  • 資深大佬 : gaolingyi

    闭包是早期没有模块化发明的私有变量的方法,现在 js 也有 class 了

  • 資深大佬 : julyclyde

    主要是逼格的问题
    闭包更加 bigger
    对象一看就是陈旧的概念了

  • 資深大佬 : walpurgis

    @yaphets666 闭包无处不在,可能你已经用了很多次而自己都没察觉,比如给 DOM 元素添加事件就是一个典型闭包应用场景

    {
    let a = 0
    document.body.addEventListener(‘click’, () => {
    a = a + 1
    console.log(a)
    })
    }

    其实这已经是闭包了,不是在函数里返回函数才叫闭包,是因为 JS 以前只有函数作用域,原谅我上面的回帖考虑不周
    出了这个块级作用域,再也不可能拿到变量 a,理应被销毁,但事件回调函数内引用了 a,需要维持环境,所以 a 不会被销毁,点击 body 可以看到 a 在不断+1
    非常简单的就创建了一个安全的私有变量,这不比 class 写法爽多了?

  • 主 資深大佬 : asanelder

    @walpurgis #41 感谢老铁解惑, 闭包确实是一种轻量级的解决方案. 写 class 总要有那么现实世界有对应之物. 显的很重

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具