一:创建单个对象的两种方式
1:通过new 操作符 加上Object 构造函数去创建
1 var person = new Object();2 person.name = "zhangsan";3 person.age = 18;4 person.job = "frontend";5 person.sayName = function () {6 alert(this.name);7 };8 console.log(person);
如果创建的对象包含大量的属性,代码会很多,为了简化创建大量属性的过程,因此出现了对象定义的简写形式,对象字面量。
2:通过对象字面量,花括号,键值对的方式去创建。
1 var person2 = {2 name: "lisi",3 age: 20,4 job: "frontend",5 sayname: function () {6 alert(this.name);7 }8 };
以上两种方法是用来创建单个对象,但是如果创建多个相似的对象时,会产生大量重复的代码因此产生了工厂函数
二:创建多个相似的对象的方式
1:工厂模式
1 function ceratPerson(name, age, job) { 2 // 原生构造函数,运行时会自动出现在执行环境中 3 var o = new Object(); 4 o.name = name; 5 o.age = age; 6 o.job = job; 7 o.sayName = function () { 8 alert(this.name); 9 };10 return o;11 }12 //可以创建多个相似的对象,同时代码量也减少了很多13 var person1 = ceratPerson("zhangsan", 18, "frontend");14 var person2 = ceratPerson("lisi", 20, "frontend");15 console.log(person1);16 console.log(person1.constructor);//function Object() { [native code] }
但是没有解决对象的标识性问题,就是无法判断创建出来的对象是什么类型的,因此出现了构造函数
2:构造函数,创建特定类型的对象
用构造函数可以创建特定类型的对象,同时也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。
1 function Person(name, age, job) { 2 this.name = name; 3 this. age = age; 4 this.job = job; 5 this.sayName = function () { 6 alert(this.name); 7 } 8 } 9 var person1 = new Person("zhangsan", 18, "frontend");10 var person2 = new Person("lisi", 20, "frontend");11 console.log(person1);12 console.log(person1.constructor);13 /* function Person(name,age,job){14 this.name = name;15 this,age = age;16 this.job = job;17 this.sayName = function () {18 alert(this.name);19 }20 }*/21 // 相对于工厂函数来说,解决了对象的标识性问题,同时代码也更加简洁。22 23 //把构造函数当做函数24 function Person(name, age, job) {25 this.name = name;26 this, age = age;27 this.job = job;28 this.sayName = function () {29 alert(this.name);30 }31 }32 //当做构造函数使用33 var person1 = new Person("zhangsan", 18, "frontend");34 person1.sayName();//zhangsan35 //当做普通函数使用36 Person("lisi", 20, "frontend"); // 添加到window37 window.sayName();//lisi38 // 在另一个对象的作用域中调用39 var o = new Object();40 Person.call(o, "wangwu", 25, "frontend");41 o.sayName();
3.原型模式(通过原型对象实现)
创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象包含了所有实例共享的属性和方法。
因此可以将属性和方法放在原型对象里面,让所有实例都可以共享。
1 function Person(){}; 2 3 Person.prototype.name='zhangsan'; 4 Person.prototype.age=20; 5 Person.prototype.sayName=function(){ 6 alert(this.name); 7 } 8 9 var person1=new Person();10 person1.sayName(); //zhangsan11 12 var person2=new Person();13 person2.sayName(); //zhangsan
先新建一个空的构造函数,然后将属性和方法添加到原型对象里面,再创建实例对象,实例对象就拥有了原型对象里的属性和方法。不管创建多少个实例对象,原型对象里的属性和方法都是共享的。
4.组合构造函数模式和原型模式
构造函数模式用于定义实例属性,原型模式则用于定义方法和共享的属性。这种混合模式不仅支持向构造函数传入参数,还最大限度地节约了内存,可谓是集两模式之长。示例代码如下:
1 function Person(name,age){ //构造函数模式 2 this.name=name; 3 this.age=age; 4 this.friends=['shelly','lucy']; 5 }; 6 7 Person.prototype.sayName=function(){ //原型模式 8 alert(this.name); 9 }10 11 var person1=new Person('zhangsan',20); //构造函数模式12 var person2=new Person('wangwu',15);13 14 person1.friends.push('van');15 alert(person1.friends); //shelly,lucy,van16 alert(person2.friends); //shelly,lucy
5.其他模式
除了以上几种常见的模式外,批量创建对象的方式还有
- 动态原型模式:仅在第一次调用构造函数时,将方法赋给原型对象的相应属性,其他示例的处理方式同构造函数模式
- 寄生构造函数模式:仅仅封装创建对象的代码,然后再返回新创建的对象,仍使用
new
操作符调用 - 稳妥构造函数模式:没有公共属性,只有私有变量和方法,以及一些
get/set
方法,用以处理私有变量。