function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log("Hello, my name is " + this.name);
};
const person = new Person("Alice", 25);
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function(){
console.log("Hello, my name is " + this.name);
}
}
const person = new Person("Alice", 25);
这两个构造函数的功能是一样的,都可以创建一个具有 name
、age
属性以及 greet
方法的 Person
对象。然而,它们的实现方式略有不同:
greet
方法是定义在 Person
的原型(prototype
)上的。这意味着所有通过该构造函数创建的对象实例都将共享同一个 greet
方法。这种方法更加高效,因为在内存中只有一个 greet
方法的副本。function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log("Hello, my name is " + this.name);
};
const person = new Person("Alice", 25);
greet
方法是在构造函数内部作为对象实例的一个属性定义的。这意味着每个通过该构造函数创建的对象实例都会拥有自己的 greet
方法副本。虽然这种实现可以满足功能需求,但它在内存使用上不够高效,因为每个实例都有自己的 greet
方法副本。function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
console.log("Hello, my name is " + this.name);
};
}
const person = new Person("Alice", 25);
尽管这两个构造函数都可以创建具有相同功能的 Person
对象,但从性能和内存使用的角度来看,第一个构造函数(将方法定义在原型上)是更好的选择。
是的,JavaScript 中的 class
语法实际上是基于原型继承和构造函数的语法糖。底层实现依然是使用构造函数和原型链。class
只是一种更简洁、更易于理解的方式来实现面向对象编程。
当你使用 class
关键字定义一个类时,JavaScript 引擎会在底层创建一个特殊的函数(构造函数)。这个构造函数具有与普通函数相同的行为,但它在语义上被视为一个类。类中定义的方法会被添加到构造函数的原型对象中。
例如,以下是一个使用 class
关键字定义的类:
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log("Hello, my name is " + this.name);
}
}
底层,这个类会被转换为一个与以下代码类似的构造函数和原型对象:
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function() {
console.log("Hello, my name is " + this.name);
};
class
关键字不仅让代码更简洁易读,还提供了一些额外的功能,如基于类的继承(通过 extends
关键字实现)和访问控制(通过 private
和 public
修饰符实现)。尽管如此,class
的底层实现仍然是基于原型继承和构造函数的。