当函数的行为类似于 class 但不使用 class 关键字或 "new" 关键字(在 Javascript 中)时,它被称为什么?

What is it called when a function behaves like a class but doesn't use the class keyword, nor "new" keyword (in Javascript)?

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

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

我认为这部分是因为我最近学习了 JS,看到 class 扔了很多东西,但翻阅了我对 not-ES5,6 的笔记,7,2018,2020 等似乎找不到 var aCounter = counterFunction() 对我来说是什么。

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

瞧,举个例子

const counterFunction = () => {
    let val = 0

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

这是||可以像这样实例化(?):

let aCounter = counterFunction() // where i'm getting tripped up

并且像

一样工作
aCounter.increment() // 1
aCounter.increment() // 2
aCounter.getVal() // 2 

我知道这很乱,但请帮忙!我认为一旦这个词汇拼图被放置到位,它会让内部的东西更多地点击!

这只是一个 returns 对象文字的函数,它不像 class (没有原型,正如你指出的那样,不使用 new, 等等).

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

相反,那些函数 closures 只要函数本身还活着,它们就会保持对变量的引用。

所以回答你的问题,你所描述的并没有具体的名字。 returns一个对象只是一个函数。

编辑:

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

const x = { a: 3, b: "hello" };

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

class A
{
    constructor() 
    {
        this.a = new Date();
        this.b = this.a.toString(); // you cannot do this in an object literal
    }
}

const x = new A();

你展示的东西没有什么特别的。它只是一个带有闭包的普通函数。

不过,您可以将其称为 design pattern 的类型。

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

下面是一个例子(虽然不是很好):

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

我知道你可能会被绊倒,让我们检查你的代码并探索发生了什么:

const counterFunction = () => {
    let val = 0

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

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


let aCounter = counterFunction() // where i'm getting tripped up

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


and works like

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

因为对象内部的方法引用了对象作用域外的变量,但是在函数体内部,创建了一个闭包,这样就可以保留val的状态。因为这个变量正在被使用,所以浏览器的清理过程跳过了它,所以这个函数仍然保留在内存中,我相信直到对象被销毁并且函数的变量不再被使用。

问题:

What is it called when a function behaves like a class but doesn't use the class keyword, nor “new” keyword (in Javascript)?

答案:

它被称为 "factory function"。

工厂函数通常 return 一致类型的对象,但不是工厂函数本身的实例。返回的对象很少会继承工厂函数的prototype属性,调用工厂函数不需要在函数被调用前new