构造函数创建对象带来的问题
上一篇文章介绍了JavaScript创建对象的几种方法,都有各自的优缺点。
构造函数看起来好像很好,但是它也有一个问题,那就是创建出来的每一个实例对象的方法都是一个独立的函数,即使他们的内容是完全相同的,这是不符合函数的代码复用原则的,而且也不能够统一的修改已被创建的实例的方法。
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.introduce = function () {
console.log("我叫" + this.name + ", 今年" + this.age + "岁.");
};
}
var jerry = new Person("Jerry", "21", "M");
var julia = new Person("Julia", "27", "F");
console.log(jerry.introduce === julia.introduce); // false
上述代码中的jerry对象和julia对象的introduce()
方法是两个独立的函数,数据不共享,如果对象创建更多就浪费了大量的内存空间。
JavaScript原型解决方案
在 JavaScript 中,每当定义一个对象(函数也是对象)时候,对象中都会包含一些预定义的属性。其中每个函数对象
都有一个 prototype 属性,这个属性指向函数的原型对象。
那么,这个原型对象有什么作用呢?
构造函数是一个函数对象
,所以就会有一个 prototype 属性,也就有了一个原型对象,既然这是一个对象,那么久可以为它添加属性和方法。而这个原型对象作为这个构造函数的一个属性,是被其创建出来的所有实例共享的。
所以上面的代码我们可以这样改写
function Person(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype.introduce = function () {
console.log("我叫" + this.name + ", 今年" + this.age + "岁.");
};
var jerry = new Person("Jerry", "21", "M");
var julia = new Person("Julia", "27", "F");
console.log(jerry.introduce === julia.introduce); // true
这样就解决了数据共享的问题,达到了代码复用的目的,无论通过此构造函数创建了多少个对象,introduce 方法只会占用一份内存空间。
且可以统一修改所有 Person 构造函数创建的实例对象的 introduce 方法。
原型对象中的方法是可以相互调用的
function Dog(name, age) {
this.name = name;
this.age = age;
}
Dog.prototype.play = function () {
console.log("小狗玩耍");
this.bark();
};
Dog.prototype.bark = function () {
console.log("小狗叫");
};
var tom = new Dog("Tom", 3);
tom.play();// 小狗玩耍 小狗叫
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。