一、工厂模式
function createPerson(name,age){
var o = new Object();
o.name = name;
o.age = age;
o.sayName = function(){
alert(this.name)
}
return o;
}
var person1 = createPerson('小明',18);
var person2 = createPerson('小红',16);
console.log(person1);
console.log(person2);
二、构造函数模式
function Person(name,age){
this.name = name;
this.age = age;
this.sayName = function(){
alert(this.name)
}
}
var person1 = new Person('小明',18);
var person2 = new Person('小红',16);
console.log(person1);//Person {name: "小明", age: 18, sayName->"小明"}
console.log(person2);//Person {name: "小红", age: 16, sayName->"小红"}
console.log(person1.constructor);//Person
console.log(person2.constructor);//Person
console.log(person1 instanceof Object);//true
console.log(person1 instanceof Person);//true
console.log(person2 instanceof Object);//true
console.log(person2 instanceof Person);//true
构造函数的问题
this.sayName = function(){alert(this.name)};
this.sayName = new Function("alert(this.name)");
person1.sayName() == person2.sayName()
一种解决办法
function Person(name,age){
this.name = name;
this.age = age;
this.sayName = sayName;
}
function sayName(){
alert(this.name)
}
三、原型模式
function Person(){}
Person.prototype.name = '小明';
Person.prototype.age = 18;
Person.prototype.sayName = function(){
alert(this.name)
}
var person1 = new Person();
var person2 = new Person();
console.log(person1);
person1.sayName();
person2.sayName();
person1.sayName == person2.sayName;
console.log(Person.prototype.isPrototypeOf(person1));
console.log(Person.prototype.isPrototypeOf(person2));
console.log(Object.getPrototypeOf(person1) == Person.prototype);
console.log(Object.getPrototypeOf(person2).name);
console.log(person1.name);
console.log(person1.hasOwnProperty('name'));
console.log('name' in person1);
person2.name = '小红';
console.log(person2.name);
console.log(person2.hasOwnProperty('name'));
console.log('name' in person2);
delete person2.name;
console.log(person2.name);
console.log(person2.hasOwnProperty('name'));
console.log('name' in person2);
console.log(Object.keys(Person.prototype))
person2.name = '小红';
console.log(Object.keys(person2))
console.log(Object.getOwnPropertyNames(Person.prototype));
console.log(Object.getOwnPropertyNames(person2))
function Person(){}
Person.prototype = {
constructor: Person,
name: '小明',
age: 18,
sayName : function(){
alert(this.name)
}
}
原型模式的问题
function Person(){};
Person.prototype = {
constructor: Person,
name: '小明',
age: 18,
friends: ['小红','小强']
}
var person1 = new Person();
var person2 = new Person();
console.log(person1.friends);//['小红','小强']
person2.friends.push('张三');
console.log(person1.friends);//['小红','小强','张三']
console.log(person2.friends);//['小红','小强','张三']
console.log(person1.friends == person2.friends); //true
//原型属性中包含一个引用类型值friends数组,所有实例中friends指向同一个数组,当其中一个发生修改,立即体现到其他实例中
四、组合使用构造函数模式和原型模式
function Person(){
this.name = '小明';
this.age = 18;
this.friends = ['小红','小强'];
};
Person.prototype = {
constructor: Person,
sayName : function(){
alert(this.name);
}
}
var person1 = new Person();
var person2 = new Person();
console.log(person1.friends);//['小红','小强']
person2.friends.push('张三');
console.log(person1.friends);//['小红','小强']
console.log(person2.friends);//['小红','小强','张三']
console.log(person1.friends == person2.friends); //false
//这样避免了原型模式的问题
五、动态原型模式
function Person(name,age){
this.name = name;
this.age = age;
if(typeof this.sayName != "function"){
Person.prototype.sayName = function(){
alert(this.name);
}
}
}
var person1 = new Person('小明',18);
person1.sayName();
六、寄生构造函数模式
function Person(name,age){
var o = new Object();
o.name = name;
o.age = age;
o.sayName = function(){
alert(this.name);
}
return o;
}
var person1 = new Person('小明',18);
person1.sayName();
寄生构造函数demo
function SpecialArray(){
var values = new Array();
values.push.apply(values,arguments);
values.tojoin = function(){
return this.join('|');
}
return values;
}
var colors = new SpecialArray('red','yellow','blue');
console.log(colors.tojoin());
七、稳妥构造函数模式
function Person(name,age){
var o = new Object();
o.sayName = function(){
alert(name)
}
return o;
}
var person1 = Person('小明',18);
person1.sayName();