答案:节省内存占用
没有 prototype 会有什么问题?
考虑一下我们在 js 中如何创建类的实例对象?先定义一个方法 Person,然后使用 new 关键词调用这个方法,我们先创建一个实例对象 freeman,然后再创建一个实例对象 newton,我们按照 Java 或者 C# 等面向对象语言的思路去考虑,我们会认为同样是人这个类的两个不同实例 freeman 和 newton,是不是应该具有同样的行为(此处是 eat 和 drink),但很不幸,如果使用这样的方法在 js 中创建这两个对象,他们的这两个行为没有半毛钱关系,为什么?因为创建这两个对象时都分别创建了自己的方法,只是名字相同而已(仅此而已)。考虑一个场景,如果我们需要创建一堆这样的实例的时候,我们每个实例都在重复创建这些方法,你会发现内存在持续增长。尤其是对于 virtual DOM 中的 element,如果每个
element 都有自己的一套方法,那对于一个普通的 html 文档来说,背后的 DOM 将占用大量的内存,从而影响到 js 的效率。
function Person(name) {
this.name = name;
this.eat = function () { console.log('eat apple.') };
this.drink = function() { console.log("drink water.") };
}
var freeman = new Person('freeman');
var newton = new Person('Newton')
freeman.eat === newton.eat // false
freeman.drink === newton.drink // false
为什么引入 prototype?
为了解决第一节中提到的问题,javascript 引入了 prototype 的概念,每个方法都默认由 javascript 执行环境添加一个 prototype 属性,这个属性本身是一个 object 对象,所以我们可以在这个 prototype 属性上添加她的属性和方法,只要使用 new 关键词创建的实例默认都集成这个 prototype 上定义的属性和方法(类似 OO 语言中的实例方法),这样无论你创建多少个实例对象,他们的行为(方法)都只有一个 blueprint,不会重复创建。
function Person(name) {
this.name = name;
}
Person.prototype.eat = function() {}
Person.prototype.eat = function() {}
var freeman = new Person('freeman');
var newton = new Person('Newton')
freeman.eat === newton.eat // true
freeman.drink === newton.drink // true