JS创建对象的六种方式

 更新时间:2025年04月09日 11:04:31   作者:sevenliao  
在js中,对象是键值对的集合,可以通过很多种方式创建; 本文给大家介绍了六种创建方式:对象字面量、构造函数、Object.create()、工厂函数、class、单例模式,需要的朋友可以参考下

1.对象字面量(Object Literal)

用法: 直接通过{}定义对象,是最简单的方式;

原理: 直接分配内存创建一个普通对象,继承object.prototype;

  • 直接内存分配: 当使用{}定义对象时,js引擎会直接在堆内存中分配一个普通对象。
  • 隐藏原型继承: 该对象的[[Prototype]](即 proto) 会自动指向 Object.prototype, 继承原始对象默认方法 (如:toString).
  • 属性初始化: 字面量中的属性和方法会直接挂载到对象自身,而非原型链。

例子:

const person {
    name: '小明',
    age: 25,
    greet() {
        console.log(`hi , i'm ${this.name}`)
    }
}
person.greet() //hi ,i'm 小明
const obj = {key:“value”};

//等价于:
const obj = new Object(); //隐式调用 Object 构造函数
obj.key = "value";

特点:

  • 适合创建单例对象或一次性对象;
  • 所有属性方法均为实例自身成员,无法共享

2.构造函数(constructor function)

用法:通过 new 关键字调用构造函数创建对象

原理: new 操作

  • 1.创建空对象: 在内存中创建一个新对象 {}
  • 2.绑定原型:将新对象的[[Prototype]] 即原型链, 指向构造函数的prototype属性
  • 3.执行构造函数:将构造函数内的this指向新对象,执行构造函数代码(初始化属性)
  • 4.返回对象: 若构造函数未显示返回其他对象,则返回新对象;

例子:

function person(name, age){
    // this = {};  (隐式操作)
    // this.__proto__ = person.prototype; (隐式操作)
    this.name = name;
    this.age = age;
    this.greet = function(){
        console.log(`hi, i'm ${this.name}`)
    }
    
    // return this;  (隐式操作)
}

const xiaoming = new person('小明', 25);
xiaoming.greet(); //hi, i'm 小明


//原型链结构: xiaoming.__proto__ -> person.prototype -> Object.prototype -> null;

缺点:每个实例的方法都是独立的,浪费内存(可以优化共享原型方法);

  • 若方法定义在构造函数内部,每个实例会有独立的方法副本(浪费内存);
  • 若方法定义在person.prototype上,所有实例共享同一方法(推荐做法)

3. Object.create()

用法:基于现有对象作为原型创建新对象。

原理:创建一个新对象,并将其Prototype 指向传入的对象;

  • 显式原型继承:直接创建一个新对象,并手动指定其[[Prototype]] 即:原型链 __ proto __
  • 参数处理: 1.若传入null, 新对象的[[Prototype]]为null (无原型链); 2.若传入对象proto, 新对象继承proto的属性和方法;

例子:

const prototypeObj = {
    greet(){
         console.log(`hi, i'm ${this.name}`)
    }
}
const person = Object.create(prototypeObj);
person.name = "小明";
person.age = 10;
person.greet(); //hi , i'm 小明

扩展:可创建无原型的对象(Object.create(null)),适合纯粹的数据存储;

4.工厂函数(Factory Function)

用法: 封装对象创建逻辑的函数,直接返回新对象;

原理:手动创建对象并返回,不依赖 new 或原型链;

  • 封装对象创建: 通过普通函数返回新对象,不依赖new或者原型链。
  • 独立实例: 每次调用工厂函数都会产生新的对象,所有属性和方法均为实例自身成员。

例子:

function createPeason(name,age){
    const obj = {}; //显示创建对象
    obj.name = name;
    obj.age = age;
    obj.greet = function(){}   //方法不共享
    return obj;
}
const xiaoming = createPeason('小明',10);
xiaoming.greet();  //hi, i'm 小明;

特点:避免 new 的使用,但方法无法共享(每个实例的方法独立)。

对比构造函数:

  • 优势: 更直观,避免new 的依赖。
  • 劣势: 方法无法共享,内存效率低。 (因为是闭包啊)

5.ES6 class 语法

用法:使用clase关键字定义类,通过new实例化;

原理:本质是构造函数的语法糖(构造函数另一种写法),基于原型链实现继承。

  • 方法挂载: 类中定义的方法会自动添加到prototype对象上,实现共享;
  • 继承机制: extends 关键字通过修改原型链实现继承(子类的prototype 指向父类实例)

例子:

class Person {
    construtor(name,age){
        this.name = name;
        this.age = age;
    }
    greet(){
        console.log(`hi, i'm ${this.name}`)
    }
}
const xiaoming = new Person('小明',10);
xiaoming.greet(); // hi, i'm 小明;

//原型链结构: xiaoming.__proto__ -> Person.prototype -> Object.prototyle -> null;

优点: 语法更清晰,支持继承(extends)和静态方法(static)

6.单例模式(Singleton)

用法:确保一个类只有一个实例;

原理:通过闭包或模块化限制实例化次数

  • 闭包封装: 通过立即执行函数(iife)和闭包保存唯一实例的引用。
  • 惰性初始化: 在首次调用时创建实例,后续调用直接返回已存在的实例;

例子:

const singleton - (function(){
    let instance;
    function createInstance() {
        return { id: Math.random() };
    }
    return {
        getInstance(){
            if(!instance) instance = createInstance();
            return instance;
        }
    }
})();

const obj1 = singleton.getInstance();
const obj2 = singleton.getInstance();
console.log(obj1 === obj2); //true

汇总 - 总结对比

方式特点适用场景
对象字面量简单直接,适合一次性对象简单数据存储、配置项
构造函数可复用,但方法定义在原型上 节省内存需要多个相似实例
Object.create()灵活控制原型链,可创建无原型的对象原型继承、纯净对象
工厂函数避免 new, 但方法无法共享简单对象生活
class语法清晰,支持继承面向对象开发
单例模式全局唯一实例全局状态管理

选择建议:

  • 简单对象: 优先用对象字面量或者工厂函数。
  • 复用和继承: 使用class或构造函数。
  • 原型控制: 使用Object.create()。
  • 全局唯一: 单例模式。

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

相关文章

  • 详解Javascript中DOM的范围

    详解Javascript中DOM的范围

    “DOM2级遍历和范围”模块定义了“范围”接口。通过范围可以选择文档中的一个区域,而不必考虑节点的界限(选择在后台完成,对用户是不可见的)。下面这篇文章主要介绍了Javascript中DOM范围的相关资料,需要的朋友可以参考下。
    2017-02-02
  • TypeScript中的类型断言[as语法|<>语法]的使用

    TypeScript中的类型断言[as语法|<>语法]的使用

    本文主要介绍了TypeScript中的类型断言[as语法|<>语法]的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • 使用Three.js 实现虎年春节3D创意页面

    使用Three.js 实现虎年春节3D创意页面

    虎年春节将至,本文使用 React + Three.js技术栈,实现趣味 3D创意页面,主要包括:ShadowMaterial、 MeshPhongMaterial等基本材质的使用、使用 LoadingManager展示模型加载进度、OrbitControls`的缓动动画、TWEEN简单补间动画效果等,感兴趣的朋友一起看看吧
    2022-01-01
  • 微信小程序滑动选择器的实现代码

    微信小程序滑动选择器的实现代码

    这篇文章主要介绍了微信小程序滑动选择器的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • JavaScript在浏览器中的执行机制

    JavaScript在浏览器中的执行机制

    既然说到了JavaScript,那么就会绕不过去执行上下文,只有理解了执行上下文才能更好的理解JavaScript本身,不过本部分不是专门讲解 JavaScript的,主要从JavaScript的执行顺序开始介绍一下JavaScript是怎样运行的
    2023-09-09
  • 如何从JavaScript数组中删除空对象

    如何从JavaScript数组中删除空对象

    JS中数组是我们较为常用的一种数据结构,下面这篇文章主要给大家介绍了关于如何从JavaScript数组中删除空对象的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • js实现刷新页面后回到记录时滚动条的位置【两种方案可选】

    js实现刷新页面后回到记录时滚动条的位置【两种方案可选】

    本文主要介绍了页面的div中有滚动条,js实现刷新页面后回到记录时滚动条的位置的两种方案,需要的朋友可以看下
    2016-12-12
  • 详解JavaScript实现动态的轮播图效果

    详解JavaScript实现动态的轮播图效果

    这篇文章主要介绍了JavaScript实现动态的轮播图效果,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • js获取本机的外网/广域网ip地址完整源码

    js获取本机的外网/广域网ip地址完整源码

    通过js获取本机的外网和广域网ip地址的方法有很多,本文为大家介绍个不错的方法,希望对大家有所帮助
    2013-08-08
  • JavaScript监听文本框回车事件并过滤文本框空格的方法

    JavaScript监听文本框回车事件并过滤文本框空格的方法

    这篇文章主要介绍了JavaScript监听文本框回车事件并过滤文本框空格的方法,涉及javascript操作文本框获取、清空及删除空格的技巧,需要的朋友可以参考下
    2015-04-04

最新评论