JavaScript 创建对象的十种方式详解

作者:拾光时间:2026-10-31 06:39:18浏览:492

本文系统总结了JavaScript中创建对象的十种方式,涵盖new Object、字面量、工厂模式、构造函数、原型模式、混合模式、动态混合、寄生构造函数、ES6 Class及闭包。深入解析各模式的适用场景、内存特性及优缺点,帮助开发者根据实际需求选择最优方案。

前言

面向对象编程是软件开发中的核心范式之一,而灵活构建对象则是衡量开发者基础能力的重要标准。本文将深入探讨JavaScript中创建对象的十种具体实现路径,并将其归纳为new Object、构造函数与原型对象、以及其他三类主要模式。

new Object

这三种方式在底层机制上均依赖于new Object,其局限性在于无法通过原型链准确识别对象的具体类型,因为它们的原型链最终都指向Object。console.log(obj.__proto__===Object.prototype); // true

new Object

const obj = new Object({name: 'wayne',age: 18})

字面量方式

const obj = {name: 'wayne',age: 18}

工厂函数方式

function createPerson(name, age) {
 	return {name,age,}
}
 const obj = createPerson('wayne', 18)

构造函数与原型对象

以下四种方法是对构造函数与原型对象机制的进一步细化与应用。

构造函数方式

若在构造函数内部定义方法,每次实例化都会重新创建该方法,导致内存资源浪费。因此,这种方式仅适合存放属性,而不适合存放方法。

function Person(name, age) {
	this.name = name
    this.age = age
    this.getInfo = function() {
        console.log(this.name, this.age)
    }
}
const obj = new Person('wayne', 18)

原型对象方式

将共享方法统一放置于原型对象中,可以有效避免重复创建相同功能的方法,从而节省内存空间。然而,这种方式并不适合存放属性,主要原因包括以下三点:

  • 通过new初始化新属性时操作不便,
  • 属性修改过程不够便捷 p1.__proto__.name = 'jack'
  • 原型对象中的属性会被所有实例共享,这可能导致新创建的实例出现数据冲突或意外覆盖的问题。
function Person() {}
Person.prototype.name = "wayne"
Person.prototype.age = 10
Person.prototype.getInfo = function() {
	console.log(this.name, this.age)
}
const p1 = new Person()
// 这里使用的是原型上的属性
p1.getInfo() // wayne 10
// 修改原型上的属性
p1.__proto__.name = 'jack'
p1.__proto__.age = 18
// 这里使用的是原型上的属性
p1.getInfo() // jack 18
const p2 = new Person()
// 修改过的属性
p2.getInfo()  // jack 18

混合模式

这是目前较为常见的实现方式,即将属性定义在构造函数中,而将方法定义在原型对象上。尽管实用,但这种模式在某种程度上违背了面向对象封装的纯粹思想。

function Person(name, age) {
	this.name = name
  this.age = age
}
Person.prototype.getInfo = function() {
	console.log(this.name, this.age)
}
const p1 = new Person(name, age)

动态混合

这是混合模式的一种改进版本,其缺陷在于语义表达不够清晰。实际上,只有第一个对象被创建时才会触发if判断逻辑。

function Person(name, age) {
	this.name = name
  this.age = age
  if (Person.prototype.getInfo === "undefined") {
  	Person.prototype.getInfo = function() {
    	console.log(this.name, this.age)
    }
  }
}
// 第一次调用时会给 Person.prototype 添加 getInfo 方法
const p1 = new Person("wayne", 18) 
const p2 = new Person("jack", 15)

寄生构造函数

与动态混合类似,但该模式通过在函数内部调用其他构造函数来实现对象的创建。

function Person(name, age) {
	this.name = name
    this.age = age
    if (Person.prototype.getInfo === "undefined") {
        Person.prototype.getInfo = function() {
            console.log(this.name, this.age)
        }
    }
}
function func(name, age) {
	const p = new Person(name, age)
    return p
}
const p1 = func("wayne", 18)

其他

class

利用ES6语法糖class来创建对象,其底层本质仍然是function。

class Person {
	constructor(name, age) {
  	this.name = name
    this.age = age
  }
  getInfo() {
  	console.log(this.name, this.age)
  }
}
const p1 = new Person("wayne", 18)
// class的本质是function
console.log(typeof Person);  //function   

闭包

借助闭包的特性同样可以实现对象的创建。其优势在于无需使用this和new关键字;然而,其劣势在于容易引发内存泄漏问题。

function Person(name, age) {
    return {
      getName() {
          return name
      },
      getAge: function() {
          return age
      }
    }
}
const p1 = Person("wayne", 18)
console.log(p1.getName()) // wayne
console.log(p1.getAge()) // 18

总结

new Object的三种

  • new Object:new Object({name: 'wayne',age: 18})
  • 字面量创建:{name: 'wayne',age: 18}
  • 工厂函数方式:function createPerson(name, age) {return {name,age,}}

构造函数与原型对象四种

  • 构造函数方式:适合属性
  • 原型对象方式:适合方法
  • 混合方式:常见的方式,将属性放在构造函数,方法放在原型上。
  • 动态混合:使用if判断是否挂载方法
  • 寄生构造函数:通过函数里调用其他构造函数

其他两种

  • class,ES6语法糖,本质为function
  • 闭包:优点:不用this 和 new;缺点:容易造成内存泄漏。

以上就是JS创建对象的十种方式总结的详细内容,更多关于JS创建对象的资料请关注本站其它相关文章!

作者最新文章