繁体   English   中英

当一个函数表现得像一个类但不使用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)?

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

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

我认为这部分是因为我最近才知道JS,看到class抛来抛去了很多,但希望通过我的 -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 

我知道这是漫无边际的,但有帮助! 我认为一旦这个词汇拼图就位,它会让东西更加点击!

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

设置为此对象(存储在aCounter )的属性的函数似乎像类方法一样,因为它们保持对变量val的引用,但这不是因为val与实际对象有任何关联。

相反,这些函数是闭包 ,只要函数本身存活,就会保持对变量的引用。

所以为了回答你的问题,你所描述的内容没有特别的名字。 它只是一个返回对象的函数。

编辑:

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

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

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

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

const x = new A();

你在那里展示的没什么特别的。 它只是一个具有闭包的普通函数。

但是,您可以将其称为一种设计模式

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

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

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


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

这是调用先前定义的函数,它再次使用两种方法返回对象并将其分配给变量aCounter 如果你为一个名为bCounter的变量再次做同样的事情,他们将拥有两个独立的对象。


and works like

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

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

题:

当一个函数表现得像一个类但不使用class关键字,也不使用“new”关键字(在Javascript中)时会调用什么?

回答:

它被称为“工厂功能”。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM