首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >当一个函数的行为像一个类,但没有使用class关键字,也没有使用"new“关键字(在Javascript中)时,它被称为什么?

当一个函数的行为像一个类,但没有使用class关键字,也没有使用"new“关键字(在Javascript中)时,它被称为什么?
EN

Stack Overflow用户
提问于 2019-01-15 11:28:09
回答 3查看 236关注 0票数 3

我查看了suggested链接,但似乎找不到与类类似的函数的术语(它是构造函数吗?也没有这个关键字!)但不使用new关键字,也不使用class

我在代码中同时使用了这个示例的模式和类模式,但我意识到我不知道如何描述前者。

我想这在一定程度上是因为我最近学习了JS,看了很多class,但通过我的not-ES5,6,7,2018,2020等的笔记,似乎找不到var aCounter = counterFunction()对我的生活的调用。

我知道我所做的事情的结果是什么,如何工作,等等,但是为什么没有constructor(),没有new,没有class,没有etc.prototype.etc模式?我知道我正在创建一个对象,调用一个存在于该对象中的方法,等等。我相信我开始漫步了。

Lo,一个例子

代码语言:javascript
复制
const counterFunction = () => {
    let val = 0

    return { 
      increment() { val++ }, 
      getVal() { return val }
    }
}

哪个是||可以实例化(?)如下所示:

代码语言:javascript
复制
let aCounter = counterFunction() // where i'm getting tripped up

它的工作原理如下

代码语言:javascript
复制
aCounter.increment() // 1
aCounter.increment() // 2
aCounter.getVal() // 2 

我知道这有点胡言乱语,但是帮帮忙!我想一旦这个词汇拼图被放到合适的位置,它会让东西在里面点击更多!

EN

回答 3

Stack Overflow用户

发布于 2019-01-15 11:36:08

这只是一个返回对象文字的函数,它的行为不像类(没有原型,正如您所指出的,不使用new等)。

设置为该对象(存储在aCounter中)的属性的函数看起来像类方法,因为它们使对变量val的引用保持活动状态,但这并不是因为val以任何方式与实际对象相关联。

相反,这些函数是closures,只要函数本身还活着,对变量的引用就会一直保持活动状态。

因此,为了回答您的问题,您所描述的内容并没有特别的名称。它只是一个返回对象的函数。

编辑:

您问到为什么在此模式中没有constructor()或相关语法。JavaScript中的对象文字只是名称和值的映射:

代码语言:javascript
复制
const x = { a: 3, b: "hello" };

为此,您不需要构造函数,并且没有原型,因为它不是使用构造函数实例化的。另一方面,类和构造函数是稍后创建的对象的模板,这些对象有一个原型和一个构造函数,因为模板包含初始化对象的逻辑。

代码语言:javascript
复制
class A
{
    constructor() 
    {
        this.a = new Date();
        this.b = this.a.toString(); // you cannot do this in an object literal
    }
}

const x = new A();
票数 3
EN

Stack Overflow用户

发布于 2019-01-15 11:40:06

你所展示的没有什么特别之处。它只是一个有闭包的普通函数。

不过,您可以将其称为一种design pattern

它看起来类似于Revealing Module Pattern,您可以将公共属性和私有属性分开。

下面是一个例子(这不是一个好的例子):

代码语言:javascript
复制
var counter = function(){

  var privateCount = 0;
  var privateHistory = [];
  
  return {
    getVal: function(){
      return privateCount;
    },
    increment: function(){
      privateCount++;
      privateHistory.push('+');
      return this.getVal();
    },
    decrement: function(){
      privateCount--;
      privateHistory.push('-');
      return this.getVal();
    },
    publicHistory: function(){
      return privateHistory;
    }
  }
}

var aCounter = counter();
console.log(aCounter.increment());
console.log(aCounter.decrement());
console.log(aCounter.publicHistory());

在这里,您不能直接操作我不公开给您的私有变量。

只有当我将函数公开给您时,您才能操作这些私有变量。在本例中,是.increment().decrement()函数。

如你所见,没有class,没有prototype,没有constructor

票数 1
EN

Stack Overflow用户

发布于 2019-01-15 11:59:09

我可以看到你是如何被绊倒的,让我们来看看你的代码,看看发生了什么:

代码语言:javascript
复制
const counterFunction = () => {
    let val = 0

    return { 
      increment() { val++ }, 
      getVal() { return val }
    }
}

此时,counterFunction是一个指向函数的变量,它本质上是一个函数名。()=>{...}是函数体或函数定义,其中的return语句显示它返回一个具有两个属性方法的未命名对象。

代码语言:javascript
复制
let aCounter = counterFunction() // where i'm getting tripped up

这将调用之前定义的函数,该函数再次返回具有两个方法的对象,并将其赋值给变量aCounter。如果您对一个名为bCounter的变量再次执行相同的操作,它们将包含两个独立的对象。

代码语言:javascript
复制
and works like

aCounter.increment() // 1
aCounter.increment() // 2
aCounter.getVal() // 2 

由于对象内的方法引用了对象范围外的变量,但在函数体内,因此创建了一个闭包,以便可以保留val的状态。因为变量正在使用中,浏览器的清理过程会跳过它,所以函数仍然保留在内存中,我相信直到对象被销毁,函数的变量不再使用。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54192311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档