一.创建对象的常见方法
(1)Object构造函数创建单个对象,早期的JavaScript开发人员经常使用该模式创建新对象。
1 var person=new Object(); 2 person.name="xiaoming"; 3 person.age=16; 4 person.job="Software Engineer"; 5 6 person.sayname=function(){ 7console.log(this.name); 8 } 9 10 person.sayname();//xiaoming
(2)使用对象字面量的方法创建单个对象,后来该方法成为创建这种对象的首选方法
1 var person={ 2name:"xiaoming", 3age:16, 4job:"Software Engineer", 5sayname:function(){ 6 console.log(this.name); 7} 8 } 9 10 person.sayname();//xiaoming
#思考#
使用以上两种方法都可以创建单个对象,但是这些方式的不足是:使用同一接口创建很多对象,会产生大量的重复代码。
eg:当我们需要创建三个person实例时(使用字面量的形式创建)
1 var person1={ 2name:"xiaoming1", 3age:16, 4job:"Software Engineer", 5sayname:function(){ 6 console.log(this.name); 7 } 8} 9 10var person2={11name:"xiaoming2",12age:16,13job:"Software Engineer",14sayname:function(){15 console.log(this.name);16 }17}18 19var person3={20name:"xiaoming3",21age:16,22job:"Software Engineer",23sayname:function(){24 console.log(this.name);25 }26}27 28person1.sayname();//xiaoming129person2.sayname();//xiaoming230person3.sayname();//xiaoming3
#思考#
为了解决这一问题,人们开始使用工厂模式的一种变体。开发人员开发了一种函数,用函数来封装以特定接口创建对象的细节。
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 console.log(this.name); 8 }; 9 return o;//注意这里返回对象o10}11 12var person1=createPerson("xiaoming1","16","Doctor");13var person2=createPerson("xiaoming2","18","Software Engineer");14 15person1.sayname();//xiaoming116person2.sayname();//xiaoming2
#思考#
可以看到,以上工厂模式的创建方法相比Object构造函数和字面量创建对象实例,确实少了很多重复的代码。可以无数次的调用createPerson()函数,每次调用都会返回一个新的对象。
但是这种模式存在的不足是:没有解决对象识别的问题,即不知道一个对象的类型。(我的理解是:虽然可以创建很多对象,但是此类对象到底是哪种类型,我们是不知道的,如果有一个具体的对象名,代表的是此类对象,那就更好了!
为了解决工厂模式的这种不足,构造函数模式出现了。
通过创建自定义的构造函数,从而定义自定对象类型的属性和方法。
1 function Person(name,age,job){ 2 this.name=name; 3 this.age=age; 4 this.job=job; 5 this.sayname=function(){ 6 console.log(this.name); 7 }; 8} 9 10var person1=new Person("xiaoming1","16","Doctor");11var person2=new Person("xiaoming2","18","Software Engineer");12 13person1.sayname();//xiaoming114person2.sayname();//xiaoming2
#思考#
可以看到构造函数模式比工厂模式又简洁了许多,重要的是,我们创建了一个可识别的对象,就是Person对象,可以通过new一个Person对象来进行对象的实例化。
对比Person和createPerson的不同是:
(1)没有显示的创建对象,在createPerson中有var o=new Object();
(2)直接将属性和方法赋给了this对象。
(3)没有return语句。
#注意#
注意:这里的Person是大写的,因为构造函数始终都应该以大写字母开头。
#思考#
以上这个例子中,person1和person2分别保存着Person的一个不同的实例,这两个对象都有一个constructor(构造函数)属性。
对象的constructor属性最初是用来标识对象类型的。例如这里:Person1和Person2这两个对象实例都是Person这个对象类型,所以返回true。
1 console.log(person1.constructor===Person);//true2 console.log(person2.constructor===Person);//true
eg:
1 A construction function 2function MyObj(){ 3 this.number=1; 4} 5 6var x=new String("Hi"); 7 8if(x.constructor==String){ 9 document.write("Object is a String"+"<br/>");10 11}12 13var y=new MyObj;14if(y.constructor==MyObj){15 document.write("Object constructor is MyObj.")16}
#另:关于对象的constructor属性参见:/zh-cn/library/c1hcx253(v=vs.94).aspx
检测对象类型:instanceof操作符。
1 console.log(person1 instanceof Object);//true2 console.log(person2 instanceof Object);//true3 console.log(person1 instanceof Person);//true4 console.log(person2 instanceof Person);//true
#到目前为止,我们创建对象的方法经历看以下改变: