JavaScript 中的函数和构造函数之间的所有区别是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22401553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 23:04:21  来源:igfitidea点击:

What are all the differences between function and constructor function in JavaScript?

javascriptfunctionconstructorthis

提问by vimal1083

In thisblog author says below function is a constructor function:

这篇博客中,作者说下面的函数是一个构造函数

function Cat(name, color) {
  this.name = name;
  this.color = color;
}
Cat.prototype.age = 0;

var catC = new Cat("Fluffy", "White");

The instances of Catfunction has a name and colour property. Is this the only difference between normal and constructorfunction?

Cat函数的实例具有名称和颜色属性。这是普通函数和构造函数之间的唯一区别吗?

回答by Denys Séguret

A constructor function is a normal function.

构造函数是一个普通函数。

What makes the difference here is the use of the newoperator which makes the context (this) in the function the new instance, thus letting it take the two properties, and returns this new instance.

这里的不同之处在于使用new运算符使this函数中的上下文 ( ) 成为新实例,从而让它采用两个属性,并返回这个新实例。

Without the newoperator, the context would have been the external one (windowif your code is in the global scope in loose mode, undefinedif in strict mode).

如果没有new运算符,上下文将是外部上下文(window如果您的代码在松散模式下的全局范围内,undefined如果在严格模式下)。

That is, if you omit the new

也就是说,如果你省略 new

var catC = Cat("Fluffy", "White");

the function "works" (if you're not in strict mode) but you have two different results :

函数“有效”(如果你不是在严格模式下)但是你有两个不同的结果:

  • catCis undefinedas your function returns nothing
  • nameand colorare now properties of the external scope
  • catCundefined因为您的函数不返回任何内容
  • name并且color现在是外部作用域的属性

The whole magic, thus, is in the new operator:

因此,整个魔术都在new 运算符中

When the code new foo(...) is executed, the following things happen:

A new object is created, inheriting from foo.prototype.

The constructor function foo is called with the specified arguments and this bound to the newly created object. new foo is equivalent to new foo(), i.e. if no argument list is specified, foo is called without arguments.

The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)

当代码 new foo(...) 被执行时,会发生以下事情:

创建一个新对象,继承自 foo.prototype。

使用指定的参数调用构造函数 foo 并将 this 绑定到新创建的对象。new foo 等价于 new foo(),即如果没有指定参数列表,则 foo 被无参数调用。

构造函数返回的对象成为整个 new 表达式的结果。如果构造函数没有显式返回对象,则使用在步骤 1 中创建的对象。(通常构造函数不返回值,但如果他们想覆盖正常的对象创建过程,他们可以选择这样做。)

When I said it's a normal function I, I omitted one thing : the intent of the developer. You usually define functions to be either called as constructors (i.e. with new) or not. In the first case you most often use the arguments to initialize the fields of the instance (using this.name = ...) and you often follow by adding functions to the prototype (as you did) so that they become available for all instances. And to make your intent clear, it's customary to name your constructor starting with an uppercase letter.

当我说这是一个正常的功能时,我忽略了一件事情:开发者的意图。您通常将函数定义为作为构造函数(即 with new)调用或不调用。在第一种情况下,您最常使用参数来初始化实例的字段(使用this.name = ...),然后您经常向原型添加函数(就像您所做的那样),以便它们可用于所有实例。并且为了明确您的意图,习惯上以大写字母开头命名您的构造函数。

回答by Anoop Rai

Let's take an example to understand the birth of constructors in Javascript. Suppose, you are asked to create an object of employee and it should have 4 properties firstName, lastName, gender , and designation. Well! you said no problem.

让我们通过一个例子来理解 Javascript 中构造函数的诞生。假设,你被要求创建一个员工对象,它应该有 4 个属性 firstName、lastName、gender 和 designation。好!你说没问题。

var employee1={};
employee1.firstName="Anoop";
employee1.lastName="Rai";
employee1.gender="M";
employee1.designation="Software Engineer";

Above is the simplest way, first you created empty object and then you associated all the 4 properties to the object (of course, you could have also created the same via inline). What if you are asked again to create another employee object with the same properties.

以上是最简单的方法,首先创建空对象,然后将所有 4 个属性关联到对象(当然,您也可以通过内联创建相同的属性)。如果您再次被要求创建另一个具有相同属性的员工对象,该怎么办?

var employee2={};
employee1.firstName="Ram";
employee1.lastName="Kumar";
employee1.gender="M";
employee1.designation="Associate Software Engineer";

Seems no problem at all. Now what if you are asked that there are total 100 employees and you just created 2 of them, common you need to create another 98 employee objects. Now you won't be creating objects like above as it seems tedious. Gotcha! let's create a factory method that will be called any number of times and it will create objects and then return it to us. Yeah! write once and will be used many times.

似乎完全没有问题。现在,如果您被问到总共有 100 名员工,而您刚刚创建了其中的 2 个,那么通常您需要创建另外 98 个员工对象。现在你不会像上面那样创建对象,因为它看起来很乏味。明白了!让我们创建一个将被调用任意次数的工厂方法,它将创建对象,然后将其返回给我们。是的!编写一次,将使用多次。

function createEmployeeObject(firstName, lastName, gender, designation){
  var employee={};
  employee.firstName=firstName;
  employee.lastName=lastName;
  employee.gender=gender;
  employee.designation=designation;
  return employee;
} 

var employee3=createEmployeeObject("Harry", "Dsouza", "M", "Project Manager");

Much convenient way, and without any duplicate codes. Just call createEmployeeObject function with your arguments and in return you get your object. What if we have several types of objects say department. Then also we will have a function that will create a department object and returns it.

非常方便的方式,并且没有任何重复的代码。只需使用您的参数调用 createEmployeeObject 函数,作为回报,您将获得您的对象。如果我们有几种类型的对象,比如部门。然后我们还将有一个函数来创建一个部门对象并返回它。

So, what is common in these kinds of functions. It is:-

那么,这些功能的共同点是什么。它是:-

  1. creating empty object

    var myObj={};

  2. returning object after populating it

    return myObj;

  1. 创建空对象

    var myObj={};

  2. 填充后返回对象

    返回我的对象​​;

Creating empty object and returning object is common across all functions that create objects. Javascript has created a shortcut that lets you not to write these lines when you are using function that creates objects. So, these 2 lines can be skipped. Way to do this is by using Constructors.

创建空对象和返回对象在所有创建对象的函数中都很常见。Javascript 创建了一个快捷方式,让您在使用创建对象的函数时不写这些行。所以,这两行可以跳过。这样做的方法是使用构造函数。

Using functions for creating objects is fairly common in Javascript, so Javascript provides shortcut that lets you write functions for creating objects. These special functions are called Constructor functions. Constructors are functions that lets you populate the object which you need to create.

使用函数创建对象在 Javascript 中相当普遍,因此 Javascript 提供了一种快捷方式,让您可以编写用于创建对象的函数。这些特殊函数称为构造函数。构造函数是让您填充需要创建的对象的函数。

function createEmployeeObject(firstName, lastName, gender, designation){
  this.firstName=firstName;
  this.lastName=lastName;
  this.gender=gender;
  this.designation=designation;
}
var employee4=new createEmployeeObject("Alan", "Marks", "F", "Business Analyst");

You must know about this keyword It points to the current object.Remember that in Constructor functions Javascript creates empty object for us, so this actually points to that object only. Javscript Construtor functions automatically returns the object after it is populated. Now how to tell Javascript that a function is called in Constructor mode, it's the new keyword that tells Javascript to treats a function as Constructor function. Everytime you need an object, use new keyword and then call a function, and then that function prepares an object for us and returns it.

你必须知道这个关键字它指向当前对象。记住在构造函数中Javascript为我们创建空对象,所以this实际上只指向那个对象。Javscript 构造函数在填充后自动返回对象。现在如何告诉 Javascript 在构造函数模式下调用函数,是 new 关键字告诉 Javascript 将函数视为构造函数。每次你需要一个对象时,使用 new 关键字然后调用一个函数,然后该函数为我们准备一个对象并返回它。

Even though Javascript is not class based, you must take care of the Constructor function name. it's not good to use camel case, use regular one.

即使 Javascript 不是基于类的,您也必须注意构造函数名称。骆驼套不好用,用普通的。

function Employee(firstName, lastName, gender, designation){
  this.firstName=firstName;
  this.lastName=lastName;
  this.gender=gender;
  this.designation=designation;
}
var employee5=new Employee("Mark", "Watson", "M", "DBA");

http://jkoder.com/javascript-constructors-why-it-should-be-used-object-oriented-programming-in-javascript/

http://jkoder.com/javascript-constructors-why-it-should-be-used-object-oriented-programming-in-javascript/

回答by Rob Sedgwick

Dystroy has it.

Dystroy 有。

Another way of saying it, is that a function becomesa 'constructor' when it is being called with the newOperator, constructinga new class instance.

另一种说法是,当一个函数被Operator调用时,它就变成了一个“构造函数”new构造了一个新的类实例。

This is also the reason for the Capitalisation convention in the function name that is mentioned, so that other devs can see that it is a constructor, and that is falls in with the current convention of naming classes

这也是提到的函数名中的Capitalization约定的原因,让其他开发者可以看到它是一个构造函数,这符合当前的命名约定 classes

回答by Abhishek Verma

In object-oriented programming, a constructor in a class is a special type of subroutine called to create an object. It prepares the new object for use, often accepting arguments that the constructor uses to set member variables required.

在面向对象的编程中,类中的构造函数是一种特殊类型的子例程,被调用以创建对象。它准备新对象以供使用,通常接受构造函数用来设置所需成员变量的参数。

So the var catC = new Cat("Fluffy", "White");creates an new instance of the constructor class Cat

所以var catC = new Cat("Fluffy", "White");创建了构造函数类的一个新实例Cat