本文通过对比在构造函数内部定义方法与使用 prototype 定义方法的区别,解释了为何后者能避免为每个实例创建独立的方法副本,从而节省内存空间。文章指出,利用 prototype 可以让所有实例共享同一份方法逻辑,这是 JavaScript 面向对象编程中重要的内存优化手段。
JavaScript 中 prototype 解决内存浪费问题
承接上文代码,我们进一步延伸讨论。
代码如下:
<script type="text/javascript">
var Person = function (name, age) {
this.name = name;
this.age = age;
this.Introduce = function () {
alert("My name is " + this.name + ".I'm " + this.age);
};
};
var person1 = new Person("飞林沙", 21);
var person2 = new Person("kym", 26);
alert(person1.Introduce == person2.Introduce);
</script> 运行结果弹出 false,表明这两个对象的方法引用并不相同。在 C# 等语言中,每个对象通常维护一个指向同一块内存地址的方法表,但 JavaScript 在构造函数内部定义方法时,每次实例化都会创建一个新的函数对象。如果声明了 100 个对象,就会生成 100 个重复的方法拷贝,造成显著的内存浪费。
为了解决这一问题,我们可以采用 prototype 属性:
代码如下:
<script type="text/javascript">
var Person = function (name, age) {
this.name = name;
this.age = age;
};
Person.prototype.Introduce = function () {
alert("My name is " + this.name + ".I'm " + this.age);
}
var person1 = new Person("飞林沙", 21);
var person2 = new Person("kym", 26);
alert(person1.Introduce == person2.Introduce);
</script> 通过这种方式即可实现方法共享。此前我也曾认为在构造函数内定义和使用 prototype 定义效果相同,直到这次偶然进行的试验才揭示了这一关键差异。