JavaScript中的对象
ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数。”严格来讲,这就相当于说对象是一组没有特性顺序的值。对象的每一个属性或方法都有一个名字,而每个名字都映射到一个值。正因为这样(以及其他将要讨论的原因),我们可以把ECMAScript的对象想象成散列表:无非就是一组名值对,其中值可以使数据或函数。
new创建对象的步骤
使用new操作符创建对象会经历的4个步骤
1.创建一个新对象;
2.将构造函数的作用域赋给新对象
3.执行构造函数中的代码
4.返回新对象
模式一
简单工厂模式:
1 function createPerson(name,age,job){ 2 var o=new Object(); 3 o.name=name; 4 o.age=age; 5 o.job=job; 6 o.sayName=function(){ 7 alert(this.name); 8 }; 9 return o; 10 }
优点:解决了创建多个相似对象,代码重复的问题;
缺点:没有解决对象识别的问题(即怎样知道一个对象的类型);
模式二
构造函数模式:
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 }
优点:可以把实例识别为一种具体的类型;
缺点:每个方法都要在每个实例上重新创建一遍;
模式三
原型模式:
1 function Person(){ 2 } 3 Person.prototype.name="Nicholas"; 4 Person.prototype.age=29; 5 person.prototype.job="Software Engineer"; 6 Person.prototype.sayName=function(){ 7 alert(this.name); 8 };
优点:可以让所有对象实例共享它所包含的属性和方法;
缺点:原型的共享本质,使所有实例共享相同属性值,对于引用类型的属性来说,改变一个实例的属性值会导致所有实例属性发生改变;
重点知识点:实例中的指针仅指向原型,与构造函数无关;
模式四
组合使用构造函数和原型模式(目前定义引用类型的一种默认模式):
1 function Person(name,age,job){ 2 this.name=name; 3 this.age=age; 4 this.job=job; 5 this.fridends=["Shelby","Court"]; 6 } 7 8 Person.prototype={ 9 constructor:Person, 10 sayName:function(){ 11 alert(this.name); 12 } 13 }
风格缺点:没有把所有信息封装在构造函数中,格式上没有封装性;
模式五
动态原型模式(保证了封装性):
1 function Person(name,age,job){ 2 this.name=name; 3 this.age=age; 4 this.job=job; 5 if(typeof this.sayName!="function"){ 6 Person.prototype.sayName=function(){ 7 alert(this.name); 8 }; 9 } 10 }
注意:使用动态原型模式时,不能使用对象字面量重写原型。如果在已经创建了实例的情况下重写原型,那么就会切断现有实例与新原型之间的关系;
模式六
寄生构造函数模式:
1 function Person(name,age,job){ 2 var o=new Object(); 3 o.name=name; 4 o.age=age; 5 o.job=job; 6 o.sayName=function(){ 7 alert(this.name); 8 }; 9 return o; 10 }
知识点:构造函数在不返回值的情况下,默认会返回新对象实例。而通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时的返回值。
用处:因为原则上不应改变原生对象的原型,因此可以用此方法为已存在的对象(Array,String等)添加特殊方法
缺点:和工厂模式没有本质区别,无法用instanceof操作符确定对象类型
模式七
工厂方法模式:
相比于简单工厂,工厂方法即提供了对象的类型,又很容易创建大量对象,即每增加一个对象只需要修改一处。举例:
1 var Factory=function(type,content){ 2 if(this instanceof Factory){ 3 var s=new this[type](content); 4 return s; 5 }else{ 6 return new Factory(type,content); 7 } 8 } 9 10 Factory.prototype={ 11 Java:function(content){ 12 //...... 13 }, 14 15 JavaScript:function(content){ 16 //...... 17 } 18 }