以前提到,构造函数方法建立对象存在着方法不共享的问题,所以引伸出了原型模式建立对象javascript
原型模式旨在建立一个模版对象,该对象的全部属性和方法被其实例所共享。java
不一样于构造函数模式建立对象只能单级即成,得益于原型链的概念,原型模式可实现相似其余OOP语言的多级继承。函数
原型链:一系列有继承关系的函数(对象)中[[prototype]]属性自底向上的指向this
先给一个例子:prototype
function Person() { } Person.prototype = { constructor: Person, name: "Jonathan", age: 23, job: developer, sayName: function() { console.log(this.name); } } person1 = new Person(); person2 = new Person();
该例子中各对象的关系以下code
//对象
每个函数(对象)均可以视为一个模版,向上看,该对象的[[prototype]]继承
function Person() { } Person.prototype = { constructor: Person, name: "Jonathan", age: 23, job: developer, sayName: function() { console.log(this.name); } } var person1 = new Person(); person1.sayName(); //"Jonathan" var person2 = new Person(); person2.sayName(); //"Jonathan" console.log(person1.sayName == person2.sayName); //true
要点ip
因为众多实例共享原型的属性,所以改变其中某个实例的属性会影响到全局,形成属性污染,例子以下:原型链
function Person(){ } Person.prototype = { constructor: Person, name : "Nicholas", age : 29, job : "Software Engineer", friends : ["Shelby", "Court"], sayName : function () { alert(this.name); } }; var person1 = new Person(); var person2 = new Person(); person1.friends.push("Van"); alert(person1.friends); //"Shelby,Court,Van" alert(person2.friends); //"Shelby,Court,Van" alert(person1.friends === person2.friends); //true
可见,person1的friends属性污染了person2的friends属性。为避免这种状况,引入组合构造函数与原型模式。
单一使用原型对象的问题在于全部属性皆共享,若不想共享某属性,则可放入构造函数中。
function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.friends = ["Boy next door", "Deep dark fantasy"]; } Person.prototype = { constructor: Person, sayName : function () { alert(this.name); } }; var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); person1.friends.push("Van"); alert(person1.friends); //"Shelby,Court,Van" alert(person2.friends); //"Shelby,Court" alert(person1.friends === person2.friends); //false alert(person1.sayName === person2.sayName); //true