创建对象 工厂模式 工厂模式优点:有了封装的概念,解决了创建多个相似对象的问题
缺点:没有解决对象识别问题,所有对象都仅是Object的实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function createPerson(name,age,job) {     var o=new Object();     o.name=name;     o.age=age;     o.job=job;     o.sayName=function(){         alert(this.name);     };     return o; } var person1=createPerson("Jack",29,"Engineer"); //检测对象类型 alert(person1 instanceof Object) //true alert(person1 instanceof Person) //error Person is not defined 
 
 
构造函数模式 构造函数模式相比工厂模式的优点就在于,构造函数模式可以将他的实例标示为特定类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function Person(name,age,job) {     this.name=name;     this.age=age;     this.job=job;     this.sayName=function(){         alert(this.name);     }; } var person1=new Person("Jack",29,"Engineer"); //检测对象类型 alert(person1 instanceof Object) //true alert(person1 instanceof Person) //true 
 
构造函数也是函数,如果不通过new 操作符调用,和其他函数没有不同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 function Person(name,age,job) {     this.name=name;     this.age=age;     this.job=job;     this.sayName=function(){         alert(this.name);     }; } //以构造函数模式调用 var person1=new Person("Jack",29,"Engineer"); person1.sayName();//Jack //以普通函数调用 Person("Lily",25,"Actor");//执行环境为全局执行环节,this指向window window.sayName();//Lily //在另一个对象的作用域中调用 var o=new Object(); Person.apply(o,["Jim",21,"Teacher"]);//扩展Person至实例对象o的作用域 o.sayName();//Jim 
 
构造函数模式缺点在于实例方法无法复用,创建两个对象person1,person2的sayName方法的不等的,解决方法可以将函数定义转至构造函数外部,构造函数这用函数指针作为对象属性,指向外部的函数定义。
但是这样的实现,首先污染了全局作用域,其次破坏了封装性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function Person(name,age,job) {     this.name=name;     this.age=age;     this.job=job;     this.sayName=sayName; } function sayName(){     alert(this.Name); } var person1=new Person("Karl",28,"Doctor"); 
 
原型模式 每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,这个对象用途是包含可以由特定类型的所有实例共享的属性和方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function Person() {     } Person.prototype.name="Jim"; Person.prototype.age=29; Person.prototype.job="Teacher"; Person.prototype.sayName=function(){     alert(this.Name); }; var person1=new Person(); person1.sayName();//"Jim" var person2=new Person(); alert(person1.sayName==person2.sayName);//true 
 
代码这构造函数、原型对象和实例对象之间关系如下图
原型模式简易写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function Person() {     } Person.prototype={     constructor:Person,//对象字面量创建了新对象,如不指定,constructor指向了Object     name:"Jim",     age:29,     job:"Teacher",     sayName:function(){         alert(this.name);     } }; 
 
原型模式的缺点:所有实例在默认情况下取得相同属性值
构造器与原型混合模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function Person(name,age,job) {         this.name=name;     this.age=age;     this.job=job;     this.friends=["Tom","Jack"]; } Person.prototype={     constructor:Person,//对象字面量创建了新对象,如不指定,constructor指向了Object     sayName:function(){         alert(this.name);     } }; var person1=new Person("Jim",25,"Teacher"); var person2=new Person("Lily",20,"Actor"); person1.friends.push("Mark"); alert(person1.friends===person2.friends);//false alert(person1.sayName===person2.sayName);//true 
 
动态原型模式 所有代码封装在构造函数,首次调用将方法添加至原型对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function Person(name,age,job) {         this.name=name;     this.age=age;     this.job=job;     this.friends=["Tom","Jack"];     //方法     if(typeof this.sayName != "function")     {         Person.prototype.sayName=function(){             alert(this.name);         };     } }