在 JavaScript 中创建对象的六种方法

在 JavaScript 中创建对象的六种方法

在 JavaScript 中创建对象的六种方法

对象是 JavaScript 中基本的数据类型之一。作为 JavaScript 开发人员,你会发现自己经常与他们合作。有用的一件事是知道如何创建它们。在本教程中,你将学习如何以六种方式在 JavaScript 中创建对象。

在 JavaScript 中,通常有多种方法可以执行相同的操作。这包括创建新对象。到目前为止,至少有六种方法可以做到这一点。本教程将向你展示上述每种方式。首先,你将学习如何使用对象文字和new关键字来创建新对象。

接下来,你将学习如何使用本机Object.create()Object.assign()方法创建对象。之后,你还将学习如何使用函数构造函数和 ES6 类来执行此操作。事不宜迟,让我们开始吧。

1:对象常量

使用对象文字是在 JavaScript 中创建对象的第一种方法。它可能也是最容易学习,记住和使用的。这可能也是为什么它是使用 JavaScript 创建对象的最流行方法的原因。用这种方法创建对象很简单。你将键值对用大括号({})括起来。

这些键值对是一对,keys并且values你希望对象具有。key经常使用的对象的另一个名称是 “属性”。键或属性位于该对的左侧,值位于右侧。在这两个之间是冒号(key: value)。

当用大括号将这对包裹时,你将得到一个对象。如果要创建一个空对象,则仅使用大括号。之后,你可以将该新对象分配给某个变量。或者,你可以根据需要立即使用它。

// Creating object with object literal.
const myObj = {
  name: 'Tom Jones',// One key-value pair.
  role: 'admin',
  isWorking: false,
  sayHi: function() {
    return `Hi, my name is ${this.name}.`
  }
}

// Log the object to console.
console.log(myObj)
// Output:
// {
//   name: 'Tom Jones',
//   role: 'admin',
//   sayHi: ƒ sayHi()
// }


// Creating an empty object with object literal.
const myEmptyObj = {}

// Log the object to console.
console.log(myEmptyObj)
// Output:
// {}

2:“new” 关键字

创建对象的第二种方法是将new关键字与 Object()构造函数一起使用。使用此构造函数时,它将返回一个值,即新对象。你可以将此对象分配给变量,以便你可以继续使用它。如果要添加新属性,可以做两件事。

第一个是创建一个空对象并将其分配给变量。然后,你可以使用点符号或使用方括号将属性添加到该对象。这样一来,你一次只能定义一个属性。因此,如果要创建多个属性,则必须执行几次。

第二种选择是将一个对象Object()作为参数传递给构造函数。这还将创建具有所需属性和值的对象。但是,如果要传递对象,则使用Object()构造函数是多余的。这可能也不是一个好习惯,因此绝对不建议这样做。

在这种情况下,你可以做的是使用对象文字方式。我们在上面的上一节中讨论了这一点。

// Creating object with object constructor.
const myObj = new Object()

// Add properties.
myObj.username = 'Skylar'
myObj.gender = 'female'
myObj.title = 'Fullstack dev'

// Add a method.
myObj.sayHi = function() {
  return `Hi, I am ${this.username}.`
}

// Log the object to console.
console.log(myObj)
// Output:
// {
//   username: 'Skylar',
//   gender: 'female',
//   title: 'Fullstack dev'
//   sayHi: ƒ ()
// }


// Passing an object - not a good idea
const myObj = new Object({
  username: 'Skylar',
  gender: 'female',
  title: 'Fullstack dev'
})

// Log the object to console.
console.log(myObj)
// Output:
// {
//   username: 'Skylar',
//   gender: 'female',
//   title: 'Fullstack dev'
// }

3:Object.create() 方法

当你要基于现有Object.create()方法创建新对象时将非常有用。此方法接受两个参数。第一个参数用于要复制的原始对象。这将是prototype。第二个参数用于具有要添加到新对象的属性和值的对象。

当你使用这种方式并添加新属性时,请记住一件事。你可以通过value[属性描述符] 而不是直接指定新属性的值。你还可以指定其他标志,如writableenumerableconfigurable。你可以对要添加的每个属性执行此操作。

Object()构造函数类似,此方法也将返回新对象。因此,在使用它时将其分配给变量,以便以后使用。

// Create new object (using object literal).
const human = {
  species: 'human',
  isAlive: true
}

// Create new object "female" with Object.create()
// and use "human" as the prototype
// and add two new properties - "gender" and "pregnant".
const female = Object.create(human, {
  // Add "gender" property.
  gender: {
    value: 'female', // Value of "gender" property.
    writable: true,
    enumerable: true,
    configurable: true
  },
  // Add "pregnant" property.
  pregnant: {
    value: false, // Value of "pregnant" property.
    writable: true,
    enumerable: true,
    configurable: true
  }
})

// Log the "female" object.
console.log(female)
// Output:
// {
//   gender: 'female',
//   pregnant: false,
//   __proto__: {
//     species: 'human',
//     isAlive: true
//   }
// }

// Log the value of "gender" property.
console.log(female.gender)
// Output:
// 'female'

// Log the value of "species" property.
// This property is inherited from "human" object.
console.log(female.species)
// Output:
// 'human'

// Log the value of "isAlive" property.
// This property is inherited from "human" object.
console.log(female.isAlive)
// Output:
// true

关于原型,原型和继承的注释

注意:speciesisAlive属性是从原始human对象继承的。如果你记录内容female对象,这两个属性将不会直接显示在其中。它们将在__proto__对象内部。该对象是原始对象human

你可以想象替换__proto__human。或者,将其替换为用作原型的任何其他对象。当你使用这两个属性时,JavaScript 将查看该原型对象以获取实际值。因此,基本上,JavaScriptfemale.isAlive将变为human.isAlive

这就是为什么未在新对象内直接列出这些属性的原因,以及为什么你仍然可以访问它们的原因。这也是为什么如果你在中更改属性值,human也会在中获得新值的原因female。例如,如果你将设置human.isAlivefalsefemale.isAlive则现在也将是false

原因是在两种情况下,你都使用相同的属性。你正在使用human.isAlive。在一种情况下,你只需更换humanfemale作为一个 “别名”。

// Log the value of "isAlive" property.
// This property is inherited from "human" object.
console.log(female.isAlive)
// Output:
// true

// Change the "isAlive" property in "human" object.
human.isAlive = false

// Log the value of "isAlive" property again.
console.log(female.isAlive)
// Output:
// false

4:Object.assign() 方法

Object.assign()方法提供了另一种在 JavaScript 中创建对象的方法。此方法非常类似于Object.create()。此方法还通过复制现有对象来创建新对象。与相比Object.create(),此方法使你可以使用任意数量的所需源对象。

使用,Object.create()你可以创建一个对象,该对象具有来自一个对象的属性。使用,Object.assign()你可以创建一个具有多个对象属性的对象。使用此方法创建新对象很简单。它有两个参数。第一个参数是你要创建的新对象。

如果你不想添加任何新属性,请传入一个空对象({})。否则,你将传递一个具有你要添加的属性的对象。第二个参数是要用作源对象的任何对象。你的新对象将从这些源对象继承其属性。

// Create some source objects.
const lang = {
  language: 'JavaScript'
}

const job = {
  jobTitle: 'Programmer'
}

const experience = {
  experienceLevel: 'senior'
}

// Create new empty object with Object.assign() method.
// Use "lang", "job" and "experience" objects.
// First argument is an empty object to create.
// Second argument are source objects.
const coderAnonymous = Object.assign({}, lang, job, experience)

// Log the "coderAnonymous" object.
console.log(coderAnonymous)
// Output:
// {
//   language: 'JavaScript',
//   jobTitle: 'Programmer',
//   experienceLevel: 'senior'
// }


// Create new object with Object.assign() method.
// Use "lang", "job" and "experience" objects
// as source objects and also add new property "name".
// First argument is an object to create with property "name".
// Second argument are source objects.
const coderJack = Object.assign({
  // Add new property "name".
  name: 'Jack'
}, lang, job, experience) // Specify source objects.

// Log the "coderJack" object.
console.log(coderJack)
// Output:
// {
//   name: 'Jack',
//   language: 'JavaScript',
//   jobTitle: 'Programmer',
//   experienceLevel: 'senior'
// }

5:函数构造函数

在 JavaScript 中创建对象的第五种方法是使用函数构造函数。这些函数构造函数看起来像常规函数。但是,有一些差异。第一个是在使用常规函数时调用或调用它。函数构造函数不是这种情况。

当你要使用函数构造函数创建对象时,可以像Object()构造函数一样使用它。你将其与new关键字一起使用。第二个区别是调用它们时,通常使用常规函数来执行某些操作。函数构造函数用于创建对象。

第三个区别是函数构造函数经常使用 this 关键字。常规功能?好吧,这取决于你的喜好和方式。不过,你不太可能使用this常规功能。在构造函数中,你将经常使用它。最后一个区别是函数构造函数的名称以大写字母开头。

让我们看一下如何创建和使用函数构造函数。首先是function关键字。接下来是函数构造函数名称,以大写字母开头。此后是函数构造函数的参数。这些参数定义了你希望使用构造函数创建的每个对象都具有的属性。

在函数体内,你可以将这些参数分配为函数构造函数的新属性。这是你使用this关键字的地方。这将允许你在创建函数构造函数时引用它。它还将允许你引用使用构造函数创建的每个实例,新对象。

当你要使用此函数构造函数时,可以像Object()构造函数一样使用它。在这种情况下,你还要根据函数构造函数采用的参数传递一些参数。如果要添加一些方法,可以。只要确保this在方法名称之前使用关键字即可。

// Create function constructor called "User".
function User(name, username, email) {
  // Assign parameters as new properties of the function constructor.
  // This allows you to use <objName>.property: userJoe.name
  // and get the value of "name" property of "userJoe" object
  // and not any other instance of User, i.e. other object.
  this.name = name
  this.username = username
  this.email = email

  // Add object method.
  this.sayHi = function() {
    return `Hi, my name is ${this.name}.`
  }
}

// Use "User" function constructor to create new objects.
const userJoe = new User('Joe', 'joe123', 'joe@hello.com')
const userCathy = new User('Catherine', 'cathy', 'Catherine@hello.com')

// Log names of new users.
console.log(userJoe.name)
// Output:
// 'Joe'

console.log(userCathy.name)
// Output:
// 'Catherine'

// Log usernames of new users.
console.log(userJoe.username)
// Output:
// 'joe123'

console.log(userCathy.username)
// Output:
// 'cathy'

// Log emails of new users.
console.log(userJoe.email)
// Output:
// 'joe@hello.com'

console.log(userCathy.email)
// Output:
// 'Catherine@hello.com'

// Call the sayHi method for all new users.
console.log(userJoe.sayHi())
// Output:
// 'Hi, my name is Joe.'

console.log(userCathy.sayHi())
// Output:
// 'Hi, my name is Catherine.'

6:ES6 Class 类

创建新对象的最后一种方法也是最新的。JavaScript 类是在 ES6 规范中引入的。类可能看起来像是新事物。他们不是。当你仔细观察它们时,你会发现它们实际上与我们刚才谈到的函数构造函数非常相似。在后台,它们也以类似的方式工作。

当你要创建新类时,请从class关键字开始。接下来,指定类的名称。之后是花括号和班级正文。在这里,你可以定义类应具有的类属性和类方法。这些属性的定义与函数构造函数中的定义类似。

你可以this在一开始就用关键字定义它们。但是,你不是直接在主体中定义它们,而是在构造函数方法中定义它们。这是每次创建类实例时都会调用的特殊方法。创建实例基本上是在基于类的基础上创建新对象。

这也是你定义类参数的地方。当你创建该类的新实例(副本)时,将使用这些参数将值传递给属性。当你要创建类的新实例(基于该实例的新对象)时,可以将类名与new关键字一起使用。

这与你在上一节中讨论函数构造函数的过程相同。如果你的类接受任何参数,则现在可以传递适当的值作为参数。你在constructor方法中定义了这些参数,并在其中将它们分配为类属性。

让我们使用User函数构造函数并将其编写为类。这将帮助你了解类似的类和函数构造函数。

// Create a new class "User".
class User {
  // Create constructor method
  // and define parameters for "name", "username" and "email".
  constructor(name, username, email) {
    this.name = name
    this.username = username
    this.email = email

    // Also, add one class method.
    this.sayHi = function() {
      return `Hi, my name is ${this.name}.`
    }
  }
}

// Use "User" class to create new instance, new object.
const userJill = new User('Jill', 'jill987', 'jill@hello.com')

// Log the content of userJill instance/object
console.log(userJill)
// Output:
// User {
//   name: 'Jill',
//   username: 'jill987',
//   email: 'jill@hello.com',
//   sayHi: ƒ (),
//   __proto__: User { constructor: ƒ User() }
// }

// Log the value of "name" property of "userJill".
console.log(userJill.name)
// Output:
// 'Jill'

// Log the value of "username" property of "userJill".
console.log(userJill.username)
// Output:
// 'jill987'

// Log the value of "email" property of "userJill".
console.log(userJill.email)
// Output:
// 'jill@hello.com'

// Call the sayHi method.
console.log(userJill.sayHi())
// Output:
// 'Hi, my name is Jill.'