news 2026/7/24 19:17:26

JS对象深度解析:从创建到原型再到ES6 Class

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JS对象深度解析:从创建到原型再到ES6 Class

前言

本文是JavaScript基础系列的第六篇,深入讲解对象的方方面面。内容包括对象的四种创建方式(new构造函数、对象字面量、工厂函数、构造函数)、属性枚举、this指向规则、原型对象与原型链、垃圾回收机制以及ES6的class语法。掌握这些内容,你将真正理解JavaScript面向对象编程的精髓。


一、对象的创建方式(四种)

1.1 new构造函数创建对象

var obj = new Object(); obj.name = "jack"; obj.age = 18;

特点:使用new关键字调用的函数称为构造函数,专门用来创建对象。

1.2 对象字面量创建对象

使用花括号{}包含属性和方法,适合在定义对象时同时设置属性值。

let obj2 = { // 完整写法 name: "tom", age: 18, gender: "男", // 属性写法二:属性名简写(ES6) // name, // 等同于 name: name // 方法写法一:完整写法 sayHi: function() { console.log("hi"); }, // 方法写法二:匿名函数提出去 // sayHi: fun, // 方法写法三:简写方式(ES6) sayHi() { console.log("hi"); } };

注意

  • 属性与方法采用键值对形式:属性名: 属性值

  • 多个属性或方法中间用逗号隔开

  • 最后一个属性或方法后面的逗号可以省略

  • 方法冒号后跟的是一个匿名函数

1.3 读取对象

// 调用对象的属性 obj2.name; // 对象名.属性名 obj2['age']; // 对象名['属性名'] // 调用对象的方法 obj2.sayHi(); // 对象名.方法名()

1.4 对象方法

定义:函数作为对象的属性保存时,称为这个对象的方法(method)

let obj = {}; obj.sayHi = function() { console.log("hi"); }; obj.sayHi(); // 调用方法

注意:方法与函数本质上没有区别,只是名称上的区分——方法依托于对象存在。


二、对象属性枚举:for...in语句

var obj = { name: "孙悟空", age: 18, gender: "男", address: "花果山" }; for (let key in obj) { console.log(key); // 输出属性名 console.log(obj[key]); // 输出属性值 }

特点

  • 对象中有几个属性,循环体就执行几次

  • 每次执行时将对象中的一个属性名赋值给变量key

  • 通过obj[key]获取对应的属性值


三、变量与属性、函数与方法的区别

对比项

变量 vs 属性

函数 vs 方法

存储内容

都是用来存储数据

都是用来实现功能

声明方式

变量单独声明;属性在对象中无需声明

函数单独存在;方法是对象的属性

使用方式

变量直接写变量名;属性通过对象.属性名

函数直接调用;方法通过对象.方法名()


四、this关键字

4.1 this的本质

解析器在调用函数时,每次都会向函数内部传递一个隐含的参数——this。this指向的是一个对象,称为函数执行的上下文对象

4.2 this的指向规则

function fun() { console.log(this.name); } var obj = { name: "孙悟空", sayName: fun }; var obj2 = { name: "沙和尚", sayName: fun }; fun(); // 1. 函数形式调用:this指向window obj.sayName(); // 2. 方法形式调用:this指向调用方法的对象(obj) obj2.sayName(); // 3. this指向obj2

this指向总结

调用方式

this指向

函数形式调用

window

方法形式调用

调用方法的那个对象

构造函数形式调用

新创建的那个对象


五、工厂函数创建对象

使用工厂方法可以大批量地创建对象。

function createObj(name, age) { let obj1 = { name: name, age: age, study() { console.log("学习"); } }; return obj1; } let p1 = createObj("jack", 18); let p2 = createObj("tom", 19);

问题:创建的对象都是Object类型,无法区分不同类型的对象(比如无法区分"人"和"狗")。


六、构造函数

6.1 构造函数定义

构造函数是一种特殊的函数,主要用来初始化对象,为对象成员变量赋值初始值,通常与new运算符一起使用。

function Person(name, age) { this.name = name; this.age = age; this.sayHi = function() { console.log("hi"); }; } let per1 = new Person("jack", 18); let per2 = new Person("tom", 18);

6.2 构造函数规范

规范

说明

函数名首字母大写

便于区分普通函数

必须使用new关键字调用

否则会污染全局作用域

使用this添加属性和方法

this指向新创建的对象

6.3 构造函数执行流程

  1. 立即创建一个新对象

  2. 将新对象设置为函数中的this

  3. 逐行执行函数中的代码

  4. 将新对象作为返回值返回

6.4 对象的实例化

  • :使用同一个构造函数创建的一类对象(如"人类")

  • 实例:通过构造函数创建的具体对象(如"刘德华")

  • 实例化:利用构造函数创建对象的过程

6.5 instanceof运算符

检查一个对象是否是一个类的实例。

console.log(per1 instanceof Person); // true console.log(per1 instanceof Object); // true(所有对象都是Object的后代)

七、构造函数优化

7.1 存在的问题

每次创建对象时,方法都会被重新创建一次,造成内存浪费。

function Person(name, age) { this.name = name; this.age = age; this.sayNam = function() { // 每次创建都会生成一个新函数 alert("hello大家好,我是" + this.name); }; }

7.2 优化方案:将方法提取到全局

function Person(name, age, gender) { this.name = name; this.age = age; this.gender = gender; this.sayNam = fun; // 所有实例共享同一个方法 } // 将方法定义在全局作用域中 function fun() { alert("hello大家好,我是" + this.name); } var per = new Person("孙悟空", 18, "男"); var per2 = new Person("猪八戒", 28, "男"); per.sayNam(); // 孙悟空 per2.sayNam(); // 猪八戒 console.log(per.sayNam === per2.sayNam); // true

问题:将函数定义在全局作用域会污染全局命名空间,也不安全。

更好的解决方案:使用原型对象


八、原型对象(prototype)

8.1 原型对象的定义

  • 每一个函数都有一个属性prototype,指向一个对象——原型对象

  • 默认情况下,原型对象是一个空对象

  • 当函数作为构造函数调用时,所创建的对象都会有一个隐含属性__proto__,指向该构造函数的原型对象

function MyClass() {} // 向原型对象添加属性和方法 MyClass.prototype.a = 1; MyClass.prototype.study = function() { console.log("study"); }; let mc = new MyClass(); console.log(mc.__proto__ === MyClass.prototype); // true

8.2 原型对象的作用

作用

说明

公共区域

所有同类实例都可访问

避免污染全局作用域

属性和方法定义在原型上,不在全局

实现属性和方法共享

所有实例共享原型上的属性和方法

8.3 属性检测

// in运算符:会沿着原型链查找 console.log('a' in p1); // true(原型上有也算) // hasOwnProperty:只检测当前对象自身 console.log(p1.hasOwnProperty('a')); // false(原型上的不算自身)

九、垃圾回收(GC)

9.1 什么是垃圾

当一个对象没有任何变量或属性对它进行引用时,我们就无法再操作该对象,这种对象就是垃圾

9.2 JS的垃圾回收机制

  • JS拥有自动的垃圾回收机制,会自动将垃圾对象从内存中销毁

  • 我们不需要也不能手动进行垃圾回收

  • 我们只需要将不再使用的对象设置为null

var obj = new Object(); // 使用对象... obj = null; // 标记为垃圾,等待回收

9.3 面试题:null一般什么时候使用?

场景

说明

垃圾回收

手动将不需要的变量设置为null

占位

准备放对象但还没想好放什么时,先用null占位

清除事件

可以用来清除事件绑定


十、ES6类语法(class)

10.1 class定义类

ES6提供了更接近传统语言的写法,通过class关键字定义类。

class Person { // 构造函数 constructor(name, age, height) { this.name = name; this.age = age; this.height = height; } // 类方法(存在prototype上) sayHi() { console.log("hi"); } } let p1 = new Person("jack", 18, 180);

说明

  • 使用class关键字声明类

  • constructor()为构造方法,可以接收参数,初始化实例属性

  • 如果没有显式定义,一个空的constructor()方法会被默认添加

  • this关键字代表实例对象

  • 普通方法(如sayHi())存在于prototype

  • pn1.constructor === pn1.prototype.constructor返回true

10.2 狗类示例

class Dog { constructor(name, age) { this.name = name; this.age = age; } sayW() { console.log("汪汪"); } } let d1 = new Dog("来福", 2); d1.sayW(); // 汪汪

总结

本文系统梳理了JavaScript对象的深入知识:

主题

核心要点

对象创建方式

new构造函数、对象字面量、工厂函数、构造函数

this指向

函数调用→window,方法调用→调用对象,构造函数→新对象

构造函数

首字母大写、new调用、this添加属性、四步执行流程

原型对象

公共区域、共享属性和方法、避免污染全局

垃圾回收

自动回收、将无用对象设为null

ES6 class

constructor构造方法、方法写在prototype上

掌握这些内容,你就真正理解了JavaScript面向对象编程的核心思想。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/24 19:17:13

RabbitMQ 消息队列:从入门到实战

1. 什么是 RabbitMQ? RabbitMQ 是一个开源的消息代理软件,实现了高级消息队列协议(AMQP)。它允许应用程序通过消息进行异步通信,支持多种消息模式,包括点对点、发布/订阅、路由和主题等。 2. 核心概念 P…

作者头像 李华
网站建设 2026/7/24 19:14:53

5分钟快速上手:Windows本地语音转文字工具的终极指南

5分钟快速上手:Windows本地语音转文字工具的终极指南 【免费下载链接】TMSpeech 腾讯会议摸鱼工具 项目地址: https://gitcode.com/gh_mirrors/tm/TMSpeech 还在为会议记录手忙脚乱?上网课笔记跟不上老师节奏?TMSpeech是一款完全免费开…

作者头像 李华
网站建设 2026/7/24 19:14:29

不是又一个 Skill 框架:Agent Skills for .NET 正式发布

目录 01 MAF 是什么:Semantic Kernel 和 Autogen 的继任者 02 Agent Skills 是什么:SKILL.md 加渐进式披露 03 四种技能源:博客说三种,文档有四种 File-based:SKILL.md 目录 Code-defined:AgentInline…

作者头像 李华
网站建设 2026/7/24 19:14:21

导购返利APP用户行为日志采集与实时返利计算的流式处理架构

导购返利APP用户行为日志采集与实时返利计算的流式处理架构 大家好,我是省赚客APP研发者微赚淘客! 在导购返利业务中,订单追踪的实时性与准确性是核心竞争力。传统的T1离线批处理模式已无法满足用户对“下单即见返利”的体验期待。为此&#…

作者头像 李华
网站建设 2026/7/24 19:13:57

彻底解放你的《艾尔登法环》:144Hz高帧率+超宽屏完全指南

彻底解放你的《艾尔登法环》:144Hz高帧率超宽屏完全指南 【免费下载链接】EldenRingFpsUnlockAndMore A small utility to remove frame rate limit, change FOV, add widescreen support and more for Elden Ring 项目地址: https://gitcode.com/gh_mirrors/el/E…

作者头像 李华