JavaScript 构造函数入门
JavaScript 提供了多种创建对象的方法。这些方法包括对象字面量、Object()
类和构造函数。本教程将向您展示第三种方法。您将了解什么是构造函数、它们的工作原理以及如何使用它们来创建对象。
对象、蓝图、构造函数
在 JavaScript 中,创建对象的方法有很多种。最简单的工具是对象字面量,new Object()
或者Object.create()
。但是,如果你想要一些更特别的东西呢?如果你创建一个对象,并将其作为创建其他类似对象的蓝图或方案,那会怎样呢?
假设你想创建几个具有相同属性(甚至方法)的对象。你当然可以用对象字面量来实现。但是,这需要复制大量代码,或者进行不必要的对象克隆,而这有时可能非常难以预测。
另一种选择是创建“构造函数”。这个构造函数可以拥有各种属性和方法,您可以使用它来创建新对象。使用此构造函数创建的每个对象都将拥有构造函数中定义的所有属性和方法。这可以节省您大量的时间和代码。
创建此构造函数的一种方法是使用ES6 中引入的JavaScript 类。另一种选择是使用“构造函数”。让我们来看看这个构造函数是什么,它是如何工作的,以及如何使用它们来创建对象。
构造函数的基础知识
构造函数的语法简单明了。如果你了解 JavaScript 函数,这一点尤其正确。两者的语法几乎相同。每个构造函数都以function
关键字开头。接下来是构造函数的名称。
构造函数的名称应以大写字母开头。这不是强制性的,但这是一种常见的惯例和良好做法。但是,如果使用小写字母,也可以。接下来是带参数的括号。即使您不想指定任何参数,也必须包含括号。
最后是括号后面带有参数的函数体。函数体中指定了构造函数的属性和方法。使用这个构造函数创建新对象时,它们都将具有这些属性和方法。
// Syntax of a constructor function:
// - function keyword
// - name of the constructor function
// - parameters for constructor function
// - body of the constructor function
function MyConstructorFunc(param) {
// Function constructor body.
}
使用构造函数创建对象
创建构造函数是一回事,使用它们创建新对象又是另一回事。幸运的是,只有一种方法可以做到这一点。当你想使用构造函数创建新对象时,可以使用new
关键字。该关键字后面跟着构造函数名称和一对括号。
如果构造函数接受任何参数,请在括号内传递所有必要的参数。否则,请将其留空。通常,您会在将新对象赋值给变量时执行此操作。请记住,您可以使用构造函数创建任意数量的对象。
// Create constructor function:
function Person() {}
// Create object with Person constructor:
const personOne = new Person()
// Create another object with Person constructor:
const personTwo = new Person()
定义属性、方法
在构造函数中定义属性和方法很简单。不过,有一件事需要记住:定义属性或方法时,必须使用this
关键字。不要使用let
、const
或var
。您不是在定义变量,而是在定义属性。
因此,在左侧,首先输入this
关键字,然后指定属性的名称。.
在两者之间添加点 ( )。在右侧,定义属性的值,就完成了。如果要定义方法,过程几乎相同。同样需要使用this
关键字,后跟方法的名称。
唯一的区别在右侧。在这里,你必须使用function
关键字。这会告诉 JavaScript 你想要定义一个函数。你也可以使用箭头函数来代替常规函数。当你定义构造函数方法时,你可以访问构造函数中已经存在的任何属性。
为了访问属性并正确引用它,你必须使用this
关键字。this
在本例中, 是构造函数本身的引用。所以,this
基本上就像constructorFunctionItself
。
// Create constructor function:
function Person() {
// Define properties "name" and "age":
this.name = 'Anonymous'
this.age = 35
// Define method "getName" that returns a short message:
this.getName = function() {
// "this" here refers to the "Person" constructor.
// "this.name" is like "Person.name".
return `Hello, my name is ${this.name}.`
}
}
// Create object with Person constructor:
const personOne = new Person()
// Log the value of "name":
console.log(personOne.name)
// Output:
// 'Anonymous'
// Log the "getName" message:
console.log(personOne.getName())
// Output:
// 'Hello, my name is Anonymous.'
// Create another object with Person constructor:
const personTwo = new Person()
// Log the value of "name":
console.log(personTwo.name)
// Output:
// 'Anonymous'
// Log the "getName" message:
console.log(personTwo.getName())
// Output:
// 'Hello, my name is Anonymous.'
在构造函数之外定义属性和方法
一种选择是,在构造函数内部定义属性和方法。另一种选择是在构造函数创建之后,在构造函数外部定义它们。在这种情况下,你将使用一个名为prototype的属性。这是JavaScript中每个函数都具有的特殊属性。
此prototype
属性是一个对象,包含构造函数上定义的所有属性和方法。它还包含constructor
属性。此属性指向您当前正在使用的构造函数。使用此属性,您可以向构造函数添加、更改或删除属性和方法。
// Create constructor function:
function Person() {
// Define properties "name" and "age":
this.name = 'Anonymous'
this.age = 35
}
// Create object with Person constructor:
const personOne = new Person()
// Create another object with Person constructor:
const personTwo = new Person()
// Add properties to Person constructor using prototype:
Person.prototype.gender = 'female'
Person.prototype.height = 1.7
// Log the value of "gender" on "personOne" object:
console.log(personOne.gender)
// Output:
// 'female'
// Log the value of "height" on "personTwo" object:
console.log(personTwo.height)
// Output:
// 1.7
// Add method "getName" to Person constructor using prototype:
Person.prototype.getName = function() {
// "this" here will correctly refer to the Person constructor.
// So, "this.name" will again basically become "Person.name".
return `Hello, my name is ${this.name}.`
}
// Log the message:
console.log(personTwo.getName())
// Output:
// 'Hello, my name is Anonymous.'
注意事项prototype
:正如您在上面的示例中看到的,有一件事需要记住。当您通过原型向构造函数添加属性或方法时,您也会将其添加到已使用该构造函数创建的所有对象中。
定义构造函数对象的属性和方法
有时你可能只想向一个对象添加属性或方法,而不是所有对象。在这种情况下,prototype
这不可行,因为那样会把属性或方法添加到所有对象。你可以直接将属性或方法添加到特定对象。例如,使用点符号。
此后,只有当前对象才会拥有该新属性或方法。使用相同构造函数创建的其他对象将不会拥有该新属性或方法。这类似于向常规对象添加属性或方法的方法。每个使用构造函数创建的对象都是一个对象。因此,这种方法在这里也适用。
// Create constructor function:
function Person() {
// Define properties "name" and "age":
this.name = 'Anonymous'
this.age = 35
}
// Create object with Person constructor:
const personOne = new Person()
// Create another object with Person constructor:
const personTwo = new Person()
// Add property "gender" only to "personOne" object:
personOne.gender = 'female'
// Add property "height" only to "personTwo" object:
personTwo.height = 1.7
// Log the value of "gender" on "personOne" object:
console.log(personOne.gender)
// Output:
// 'female'
// Log the value of "height" on "personOne" object:
console.log(personOne.height)
// Output:
// undefined // <= this is correct, height exists only on personTwo
// Log the value of "gender" on "personTwo" object:
console.log(personTwo.gender)
// Output:
// undefined // <= this is correct, gender exists only on personOne
// Log the value of "height" on "personTwo" object:
console.log(personTwo.height)
// Output:
// 1.7
// Add "getGender()" method only to "personOne" object:
personOne.getGender = function() {
return `I am a ${this.gender}.`
}
// Add "getHeight()" method only to "personTwo" object:
personTwo.getHeight = function() {
return `I am ${this.height}m tall.`
}
// Call the "getGender()" method on "personOne" object:
console.log(personOne.getGender())
// Output:
// 'I am a female.'
// Call the "getHeight()" method on "personOne" object:
console.log(personOne.getHeight())
// Output:
// TypeError: personOne.getHeight is not a function
// Call the "getGender()" method on "personTwo" object:
console.log(personTwo.getGender())
// Output:
// TypeError: personTwo.getGender is not a function
// Call the "getHeight()" method on "personTwo" object:
console.log(personTwo.getHeight())
// Output:
// 'I am 1.7m tall.'
构造函数和参数
为对象创建蓝图的选项很棒。到目前为止,您已经看到了构造函数的示例,其中所有数据都是静态的,无法更改。这并不意味着这是唯一的方法。在一开始,当我们讨论语法时,我简要提到了参数。
这就是使构造函数更具动态性的方法。就像可以为常规函数定义参数一样,也可以为构造函数定义参数。对于构造函数,在创建对象时使用new
关键字 指定参数。这些参数传递到构造函数名称后面的括号中。
当你为构造函数定义一些参数后,就可以在构造函数内部的任何地方使用它。以Person
你在本教程中一直在使用的构造函数为例。它通常包含两个属性:name
和age
。让所有对象都拥有相同的这两个属性是没有意义的。
您可以为构造函数添加两个参数,而不是将两个属性都定义为静态值。每个属性一个参数。然后,在构造函数内部,您可以使用这些参数为这些属性赋值。这样,您就可以创建具有不同值的name
对象age
。
// Create constructor function
// that accepts two parameters, "name" and "age":
function Person(name, age) {
// Define properties and assign them
// with values provided for "name" and "age":
this.name = name
this.age = age
}
// Create object with Person constructor:
const personOne = new Person('Stan', 33)
// Create another object with Person constructor:
const personTwo = new Person('July', 29)
// Log the value of "name" on "personOne" object:
console.log(personOne.name)
// Output:
// 'Stan'
// Log the value of "age" on "personOne" object:
console.log(personOne.age)
// Output:
// 33
// Log the value of "name" on "personTwo" object:
console.log(personTwo.name)
// Output:
// 'July'
// Log the value of "age" on "personTwo" object:
console.log(personTwo.age)
// Output:
// 29
关于构造函数和 this 的说明
this
使用构造函数时,关键字非常重要。定义新属性和方法时会用到它。访问属性和调用方法时也会用到关键字this
。不过,关键字的使用频率并不重要this
。
理解什么this
是,它指的是什么,有时仍然很难回答。答案很简单。的值this
可以是以下两种情况之一。首先,当你在函数构造函数中时,值就是构造函数。
其次,当你使用构造函数创建新对象时, 的值this
将成为新对象。这将适用于你创建的每个实例、每个新对象。 的值this
始终是该特定对象。
// Create constructor function:
function Person(name, age) {
// "this" here refers to the constructor function.
// this.name => Person.name
this.name = name
this.age = age
}
const objJoe = new Person('Joe', 19)
// For "objJoe" object the value of "this"
// will be the "objJoe" object itself.
// So, "this.name" in constructor will become "objJoe.name".
console.log(objJoe.name)
// Output:
// 'Joe'
const objTim = new Person('Tim', 23)
// For "objTim" object the value of "this"
// will be the "objTim" object itself.
// So, "this.name" in constructor will become "objTim.name".
console.log(objJoe.name)
// Output:
// 'Tim'
结论:JavaScript 构造函数入门
当你想要创建多个具有相同结构但代码量较少的对象时,构造函数会非常有用。它们还能让你的代码更易于修改和维护。希望本教程能帮助你理解什么是构造函数、它们的工作原理以及如何使用它们来创建对象。
文章来源:https://dev.to/alexdevero/getting-started-with-javascript-constructor-functions-1bfi