主题:创建对象
原型模式
JavaScript中的每个对象都有一个prototype属性(原型属性),这个属性是一个指针,指向一个对象,而这个对象可以由一些属性和方法组成。被指向的对象,可以是多个对象的原型,这样创建的对象就共享了一个原型对象。
1 function Person() { 2 } 3 4 Person.prototype.name = "xuchaoi"; 5 Person.prototype.age = 24; 6 Person.prototype.sayName = function() { 7 alert(this.name); 8 }; 9 10 var person1 = new Person(); 11 var person2 = new Person(); 12 alert(person1.name === person2.name); //true
这里可提炼一下,用更简洁的方式实现。但需要注意contructor属性的变化!
function Person() { } //注意:用下面的方式的话Person.prototype的contructor属性就指向对象{...}了,这里通过设置contructor属性去除不想要的结果 Person.prototype = { contructor: Person, name: "xuchaoi", age: 24, sayName: function() { alert(this.name); }; var person1 = new Person(); var person2 = new Person(); alert(person1.name === person2.name); //true
但这种模式存在一个很大的缺点,若共享的属性中存在引用类型,就会存在一个对象该属性修改后,所有对象的该属性都被修改。
1 function Person() { 2 } 3 Person.prototype.name = "xuchaoi"; 4 Person.prototype.friends = ["小明","小红"]; 5 Person.prototype.sayName = function() { 6 alert(this.name); 7 }; 8 var person1 = new Person(); 9 var person2 = new Person(); 10 person1.friends.push("小王"); 11 alert(person2.friends); //"小明,小红,小王"
为了解决这个问题,我们可以把构造函数与原型模式进行组合使用。不能共享的属性放在构造函数中,原型模式中放一些共享的属性。这是目前JavaScript中使用最为广泛、认可度最高的一种创建自定义类型的方式。
1 function Person(name, age) { 2 this.name = name; 3 this.age = age; 4 this.friends = ["小红", "小明"]; 5 } 6 7 Person.prototype = { 8 contructor : Person, 9 sayName : function() { 10 alert (this.name); 11 } 12 } 13 var person1 = new Person("xu1", 20); 14 var person2 = new Person("xu2", 21); 15 person1.friends.push("小王"); 16 alert(person1.friends); //"小红,小明,小王" 17 alert(person2.friends); //"小红,小明"
此外还有:
寄生构造函数模式(函数内部封装一个创建对象过程,然后再返回这个创建的对象)
1 function Person(name, age) { 2 var o = new Object(); 3 o.name = name; 4 o.age = age; 5 o.sayName = function() { 6 alert(this.name); 7 }; 8 return o; 9 } 10 var person1 = new Person("xuchaoi", 20); 11 person1.sayName(); //"xuchaoi"
稳妥构造函数模式(类似于寄生构造函数模式,但构造函数内部的创建对象过程中不使用this,不使用new来调用构造函数)
1 function Person(name, age) { 2 var o = new Object(); 3 o.name = name; 4 o.age = age; 5 o.sayName = function() { 6 alert(name); 7 }; 8 return o; 9 } 10 var person1 = Person("xuchaoi", 20); 11 person1.sayName(); //"xuchaoi"