大家好,我是江城开朗的豌豆,一名拥有6年以上前端开发经验的工程师。我精通HTML、CSS、JavaScript
等基础前端技术,并深入掌握Vue、React、Uniapp、Flutter
等主流框架,能够高效解决各类前端开发问题。在我的技术栈中,除了常见的前端开发技术,我还擅长3D开发,熟练使用Three.js
进行3D图形绘制,并在虚拟现实与数字孪生技术上积累了丰富的经验,特别是在虚幻引擎开发方面,有着深入的理解和实践。
我一直认为技术的不断探索和实践是进步的源泉,近年来,我深入研究大数据算法的应用与发展,尤其在数据可视化和交互体验方面,取得了显著的成果。我也注重与团队的合作,能够有效地推动项目的进展和优化开发流程。现在,我担任全栈工程师,拥有CSDN博客专家认证及阿里云专家博主称号,希望通过分享我的技术心得与经验,帮助更多人提升自己的技术水平,成为更优秀的开发者。
技术qq交流群:906392632
大家好,我是小杨,一个在前端摸爬滚打多年的老司机。今天咱们来聊聊JavaScript中创建对象的两种主要方式------构造函数和Class。别看这俩货长得不一样,其实骨子里流淌着相同的血液。到底该用哪个?它们有什么区别?且听我慢慢道来~
一、构造函数:老派但可靠的家伙
构造函数可以说是JavaScript中的老前辈了,从JS诞生之初就存在。它的工作很简单------创建对象。
javascript
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
console.log(`大家好,我是${this.name},今年${this.age}岁~`);
};
}
const me = new Person('我', 18);
me.greet(); // 输出:大家好,我是我,今年18岁~
这里有几个关键点:
- 构造函数通常以大写字母开头(约定俗成)
- 使用
new
关键字调用 - 内部使用
this
来设置属性
构造函数虽然简单直接,但有个小缺点------每次创建实例时,方法都会被重新创建,有点浪费内存。聪明的开发者们想出了把方法放在原型上的解决方案:
javascript
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log(`大家好,我是${this.name},今年${this.age}岁~`);
};
这样所有实例共享同一个方法,节省了内存。
二、Class:语法糖的华丽转身
ES6引入了Class语法,让面向对象编程看起来更亲切(特别是对那些从Java、C++转过来的同学)。但要注意,Class本质上还是基于原型的语法糖!
javascript
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`大家好,我是${this.name},今年${this.age}岁~`);
}
}
const me = new Person('我', 25);
me.greet(); // 输出:大家好,我是我,今年25岁~
Class版本看起来更整洁,方法自动放在原型上,还支持一些高级特性:
- 静态方法
- 私有字段(ES2022正式支持)
- 继承更简单(extends关键字)
三、构造函数 vs Class:终极对决
特性 | 构造函数 | Class |
---|---|---|
语法 | 函数形式 | 使用class关键字 |
方法定义 | 需手动添加到原型 | 自动放在原型上 |
继承 | 较复杂(组合继承等) | 简单(extends) |
静态成员 | 手动添加 | 使用static关键字 |
私有成员 | 靠约定(如_name) | 使用#前缀(ES2022) |
提升 | 有函数提升 | 无提升(TDZ) |
四、我该用哪个?
这个问题就像问"该用筷子还是叉子"------取决于场景和个人喜好。不过小杨的建议是:
- 新项目:优先使用Class,语法更现代,团队协作更友好
- 老项目维护:保持原有风格(如果是构造函数就别硬改)
- 需要极致性能:构造函数在某些极端情况下可能微快(但99%场景没差别)
- 需要支持非常老的浏览器:可能需要Babel转译Class
五、来点有趣的:继承大比拼
看看两种方式实现继承的区别:
构造函数版继承:
javascript
function Programmer(name, age, language) {
Person.call(this, name, age);
this.language = language;
}
Programmer.prototype = Object.create(Person.prototype);
Programmer.prototype.constructor = Programmer;
Programmer.prototype.code = function() {
console.log(`${this.name}正在用${this.language}写代码`);
};
Class版继承:
javascript
class Programmer extends Person {
constructor(name, age, language) {
super(name, age);
this.language = language;
}
code() {
console.log(`${this.name}正在用${this.language}写代码`);
}
}
明显Class版本简洁多了吧?这就是为什么现代开发更推荐使用Class。
六、一些你可能不知道的小秘密
-
Class本质还是函数:
javascriptconsole.log(typeof Person); // "function"
-
Class中的方法不可枚举:
javascript// 构造函数版本 console.log(Object.keys(me)); // ["name", "age"] // Class版本 console.log(Object.keys(me)); // ["name", "age"] // greet方法不会出现在keys中
-
Class必须用new调用:
javascriptPerson(); // 构造函数:可能意外污染全局 Person(); // Class:直接报错
七、总结
构造函数和Class就像JavaScript对象创建的两个面,本质上做着相同的事情,只是表达方式不同。Class提供了更优雅的语法和更安全的特性,而构造函数则更接近JavaScript的原型本质。
作为开发者,理解两者的关系和区别很重要,这样无论遇到什么代码都能游刃有余。记住,在JavaScript中,Class不是传统的"类",它只是原型继承的语法糖衣。
我是小杨,一个喜欢刨根问底的前端开发者。如果你觉得这篇文章有帮助,不妨点个赞~ 下期我们可能会聊聊"this"的奇妙冒险,敬请期待!