您现在的位置是:网站首页 > 构造器模式(Constructor)与传统类的区别文章详情
构造器模式(Constructor)与传统类的区别
陈川
【
JavaScript
】
21792人已围观
6014字
构造器模式(Constructor)与传统类的区别
构造器模式是JavaScript中创建对象的一种方式,它利用函数作为对象的构造器。传统类则是ES6引入的语法糖,基于原型继承但提供了更接近传统面向对象语言的写法。两者在实现对象创建和继承时存在显著差异。
基本语法对比
构造器模式使用普通函数作为构造器,通过new
关键字实例化对象:
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
return `Hello, I'm ${this.name}`;
};
}
const john = new Person('John', 30);
传统类使用class
关键字定义:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, I'm ${this.name}`;
}
}
const john = new Person('John', 30);
原型继承机制
构造器模式显式操作原型链:
function Animal(name) {
this.name = name;
}
Animal.prototype.speak = function() {
return `${this.name} makes a noise`;
};
function Dog(name) {
Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.speak = function() {
return `${this.name} barks`;
};
类继承使用extends
关键字简化了原型链操作:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a noise`;
}
}
class Dog extends Animal {
speak() {
return `${this.name} barks`;
}
}
方法定义差异
构造器模式中方法可以定义在构造函数内部(实例方法)或原型上:
// 实例方法 - 每个实例都有独立副本
function Car(model) {
this.model = model;
this.start = function() {
return `${this.model} starts`;
};
}
// 原型方法 - 所有实例共享
Car.prototype.stop = function() {
return `${this.model} stops`;
};
类语法将所有方法默认定义在原型上:
class Car {
constructor(model) {
this.model = model;
}
start() {
return `${this.model} starts`;
}
stop() {
return `${this.model} stops`;
}
}
静态成员实现
构造器模式通过直接给构造函数添加属性实现静态成员:
function MathUtils() {}
MathUtils.PI = 3.14159;
MathUtils.sum = function(a, b) {
return a + b;
};
类语法使用static
关键字声明静态成员:
class MathUtils {
static PI = 3.14159;
static sum(a, b) {
return a + b;
}
}
私有成员模拟
构造器模式使用闭包模拟私有成员:
function Counter() {
let count = 0; // 私有变量
this.increment = function() {
return ++count;
};
this.getCount = function() {
return count;
};
}
类语法可以使用WeakMap或Symbol实现类似效果:
const _count = new WeakMap();
class Counter {
constructor() {
_count.set(this, 0);
}
increment() {
let count = _count.get(this);
_count.set(this, ++count);
return count;
}
get count() {
return _count.get(this);
}
}
提升行为差异
构造器函数会提升到作用域顶部:
const p = new Person('John'); // 可以正常执行
function Person(name) {
this.name = name;
}
类声明不会提升:
const p = new Person('John'); // ReferenceError
class Person {
constructor(name) {
this.name = name;
}
}
类型检查方式
构造器模式使用instanceof
检查原型链:
function Vehicle() {}
function Car() {}
Car.prototype = Object.create(Vehicle.prototype);
const myCar = new Car();
console.log(myCar instanceof Vehicle); // true
类继承同样使用instanceof
但语法更直观:
class Vehicle {}
class Car extends Vehicle {}
const myCar = new Car();
console.log(myCar instanceof Vehicle); // true
方法枚举性
构造器模式原型上的方法默认可枚举:
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
return `Hello, ${this.name}`;
};
const john = new Person('John');
console.log(Object.keys(john)); // ['name']
for (let key in john) {
console.log(key); // 'name', 'greet'
}
类方法默认不可枚举:
class Person {
constructor(name) {
this.name = name;
}
greet() {
return `Hello, ${this.name}`;
}
}
const john = new Person('John');
console.log(Object.keys(john)); // ['name']
for (let key in john) {
console.log(key); // 'name'
}
构造函数调用限制
构造器函数可以不使用new
调用,但可能导致问题:
function Point(x, y) {
this.x = x;
this.y = y;
}
const p1 = new Point(1, 2); // 正确
const p2 = Point(3, 4); // 错误,this指向全局对象
类构造器必须使用new
调用:
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
}
const p1 = new Point(1, 2); // 正确
const p2 = Point(3, 4); // TypeError
原型属性访问
构造器模式可以直接访问和修改原型:
function Person() {}
Person.prototype.species = 'Human';
console.log(Person.prototype); // { species: 'Human', constructor: ƒ }
类语法通过访问器属性prototype
间接访问:
class Person {
static get species() {
return 'Human';
}
}
console.log(Person.prototype); // Person {}
多构造函数支持
构造器模式可以轻松实现多个构造函数:
function Circle(radius) {
this.radius = radius;
}
function Rectangle(width, height) {
this.width = width;
this.height = height;
}
function createShape(type, ...args) {
const constructors = { Circle, Rectangle };
return new constructors[type](...args);
}
类语法需要额外处理:
class Circle {
constructor(radius) {
this.radius = radius;
}
}
class Rectangle {
constructor(width, height) {
this.width = width;
this.height = height;
}
}
function createShape(type, ...args) {
const classes = { Circle, Rectangle };
return new classes[type](...args);
}
性能考量
构造器模式在方法定义上可能产生更多内存消耗:
function Person(name) {
this.name = name;
this.sayName = function() {
console.log(this.name);
}; // 每个实例都会创建新函数
}
类方法共享原型上的函数:
class Person {
constructor(name) {
this.name = name;
}
sayName() {
console.log(this.name);
} // 所有实例共享同一函数
}
设计模式应用
构造器模式常用于实现工厂模式:
function createEmployee(type) {
switch(type) {
case 'manager':
return new Manager();
case 'developer':
return new Developer();
default:
throw new Error('Unknown employee type');
}
}
类语法可以与静态工厂方法结合:
class Employee {
static create(type) {
switch(type) {
case 'manager':
return new Manager();
case 'developer':
return new Developer();
default:
throw new Error('Unknown employee type');
}
}
}