一:创建单个对象的两种方式
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();//zhangsan 35 //当做普通函数使用 36 Person("lisi", 20, "frontend"); // 添加到window 37 window.sayName();//lisi 38 // 在另一个对象的作用域中调用 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(); //zhangsan 11 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,van 16 alert(person2.friends); //shelly,lucy
5.其他模式
除了以上几种常见的模式外,批量创建对象的方式还有
- 动态原型模式:仅在第一次调用构造函数时,将方法赋给原型对象的相应属性,其他示例的处理方式同构造函数模式
- 寄生构造函数模式:仅仅封装创建对象的代码,然后再返回新创建的对象,仍使用
new
操作符调用 - 稳妥构造函数模式:没有公共属性,只有私有变量和方法,以及一些
get/set
方法,用以处理私有变量。