简体   繁体   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)?

I looked through the suggested links but can't seem to find the term for a function that acts like a class (is it a constructor function? doesn't have that keyword either!) but doesn't use the new keyword, nor class . 我查看了建议的链接,但似乎无法找到一个类似于类的函数的术语(它是一个构造函数吗?也没有该关键字!)但不使用new关键字,也没有class

I've used both this example's pattern and the class pattern in my code but realized I don't know how to describe the former. 我已经在我的代码中使用了这个示例的模式和类模式,但意识到我不知道如何描述前者。

I think this is in part because I learned JS recently, have seen class thrown around a lot, yet looking through my notes of not -ES5,6,7,2018,2020 etc. can't seem to find what var aCounter = counterFunction() is called for the life of me. 我认为这部分是因为我最近才知道JS,看到class抛来抛去了很多,但希望通过我的 -ES5,6,7,2018,2020等笔记似乎无法找到什么var aCounter = counterFunction()被称为我的生命。

I know what the result of what i'm doing is, how to work it, etc. but why no constructor() , no new , no class , no etc.prototype.etc pattern? 我知道我正在做什么的结果是什么,如何工作,等等,但为什么没有constructor() ,没有new ,没有class ,没有etc.prototype.etc模式? I know i'm creating an object, calling a method existing Within the object, etc. I believe i'm beginning to ramble. 我知道我正在创建一个对象,调用对象中存在的方法等等。我相信我开始絮絮叨叨。

Lo, an example 罗,一个例子

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

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

which is || 这是|| can be instantiated (?) like so: 可以像这样实例化(?):

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

and works like 并且工作得像

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

I know this is rambling, but help! 我知道这是漫无边际的,但有帮助! I think it will make things click more inside once this lexical puzzle piece is put into position! 我认为一旦这个词汇拼图就位,它会让东西更加点击!

That is just a function that returns an object literal, which does not act like a class (doesn't have a prototype, and as you pointed out, does not use new , etc). 这只是一个返回一个对象文字的函数,它不像一个类(没有原型,正如你所指出的那样,不使用new等)。

The functions that are set as the properties of this object (which you store in aCounter ) seem to act like class methods because they keep the reference to the variable val alive, but this is not because val is in any way associated with the actual object. 设置为此对象(存储在aCounter )的属性的函数似乎像类方法一样,因为它们保持对变量val的引用,但这不是因为val与实际对象有任何关联。

Instead, those functions are closures that keep the reference to the variable alive for as long as the functions themselves are alive. 相反,这些函数是闭包 ,只要函数本身存活,就会保持对变量的引用。

So to answer your question, what you have described doesn't have any name in particular. 所以为了回答你的问题,你所描述的内容没有特别的名字。 It's just a function that returns an object. 它只是一个返回对象的函数。

Edit: 编辑:

You asked why there is no constructor() or related syntax in this pattern. 你问为什么在这种模式中没有constructor()或相关语法。 Object literals in JavaScript are just mappings of names and values: JavaScript中的对象文字只是名称和值的映射:

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

You do not need a constructor for this, and there is no prototype because it was not instantiated using a constructor. 您不需要构造函数,也没有原型,因为它没有使用构造函数进行实例化。 On the other hand, classes and constructor functions are templates for objects that will be created later, and those objects do have a prototype and a constructor because the template contains logic that initializes the object. 另一方面,类和构造函数是稍后将创建的对象的模板 ,这些对象确实具有原型和构造函数,因为模板包含初始化对象的逻辑。

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

const x = new A();

What you showed there is nothing special. 你在那里展示的没什么特别的。 It is just a normal function that has a closure. 它只是一个具有闭包的普通函数。

Though, you can call it as a type of design pattern . 但是,您可以将其称为一种设计模式

It looks similar to Revealing Module Pattern where you can separate public property and private property. 它看起来类似于Revealing Module Pattern ,您可以将公共财产和私有财产分开。

Below is an example (not a good one tho): 下面是一个例子(不是一个好的):

 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()); 

Here, you can't directly manipulate the private variables that I don't expose to you. 在这里,您无法直接操作我不向您公开的私有变量。

You can only manipulate those private variables only if I expose the function to you. 只有在我向您公开函数时,您才能操作这些私有变量。 In this case, the .increment() and .decrement() function. 在这种情况下, .increment().decrement()函数。

As you can see, there is no class , no prototype , no constructor . 如您所见,没有class ,没有prototype ,没有constructor

I can see how you may get tripped up, let's go through your code and explore what's going on: 我可以看到你如何被绊倒,让我们通过你的代码并探索正在发生的事情:

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

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

At this point counterFunction is a variable that points to a function, it's essentially a function name. 此时, counterFunction是一个指向counterFunction的变量,它本质上是一个函数名。 The ()=>{...} is the function body or function definition and within it the return statement shows that it returns an unnamed object with two property methods. ()=>{...}是函数体或函数定义,在其中, return语句显示它返回一个带有两个属性方法的未命名对象。


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

This is calling your previously defined function, which again returns the object with two methods and assigns it to the variable aCounter . 这是调用先前定义的函数,它再次使用两种方法返回对象并将其分配给变量aCounter If you did the same thing again for a variable called bCounter they would hold two independent objects. 如果你为一个名为bCounter的变量再次做同样的事情,他们将拥有两个独立的对象。


and works like

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

Because the method inside the object refers to a variable outside the scope of the object, but within the function body, a closure is created so that the state of val may be retained. 因为对象内部的方法引用了对象范围之外的变量,但是在函数体内,创建了一个闭包,以便可以保留val的状态。 Because the variable is in use, the browser's cleanup process skips over it, so the function is still kept in memory, I believe until the object is destroyed and the function's variable is no longer used. 因为变量正在使用中,浏览器的清理过程会跳过它,所以函数仍保留在内存中,我相信直到对象被销毁并且不再使用函数的变量。

Question: 题:

What is it called when a function behaves like a class but doesn't use the class keyword, nor “new” keyword (in Javascript)? 当一个函数表现得像一个类但不使用class关键字,也不使用“new”关键字(在Javascript中)时会调用什么?

Answer: 回答:

It's called a "factory function". 它被称为“工厂功能”。

Factory functions usually return a object of a consistent type but are not instances of the factory function itself. 工厂函数通常返回一致类型的对象,但不是工厂函数本身的实例。 Returned objects would rarely inherit from the factory function's prototype property, and calling the factory function does not require new before the function being called. 返回的对象很少会从工厂函数的prototype属性继承,并且在调用函数之前调用工厂函数不需要new

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

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