javascript中创建对象的几种不同方法
javascript中创建对象的几种不同方法
方法一:最直白的方式:字面量模式创建
1 <script> 2 var person={ 3 name:"小明", 4 age:20, 5 sex:"男", 6 hobby:function(){ 7 console.log("打篮球"); 8 } 9 }; 10 </script>
这种方法代码量多,用于“一开始就确定好内部数据类型的”对象创建。
方法二:调用系统构造函数创建
1 <script> 2 var per=new object(); 3 per={}; 4 per.name="小明"; 5 per.age="20"; 6 per.hobby=function(){ 7 console.log("打篮球"); 8 }; 9 </script>
这种方法可以先调用object来创建一个空的对象,然后动态地在后面添加对象需要的属性,但是代码量也很多。当创建一个跟它相似的对象时可能会重复使用到添加属性的代码语句,不够简洁。
方法三:工厂模式创建
1 <script> 2 function createperson(name,age){ 3 var p=new object(); 4 p.name=name; 5 p.age=age; 6 p.hobby=function(){ 7 console.log("打篮球"); 8 }; 9 } 10 var person1=createperson("小明","20"); 11 var person2=createperson("小米","18"); 12 </script>
这种方法可以解决方法二的问题,即要创建多个相似的对象时只需要调用多次函数就好,但是工厂模式创建对象无法识别对象的类型,它们都是object()构造函数创建,都是object类型(所有的对象都是object的后代),不像其他方法array()、date()等.
方法四:自定义构造函数创建
构造函数就是一个普通的函数,创建方式和普通函数没有区别,不同的是构造函数习惯上首字母大写。另外就是调用方式的不同,普通函数是直接调用,而构造函数需要使用new关键字来调用。
1 <script> 2 function person("name","age"){ 3 this.name=name; 4 this.age=age; 5 this.hobby=function(){ 6 console.log("打篮球"); 7 }; 8 } 9 var person1=new person("小明","20"); 10 var person2=new person("小米","18"); 11 </script>
这种方法与工厂模式创建有几个不同点:1.函数名person是大写,而工厂模式的函数creatperson是小写(习惯上这样用而已);2.该方法没有return语句,而工厂函数创建有return;3.该方法直接将属性和方法赋值给了this对象,而工厂模式没有出现this对象;4.该方法通过new操作符来实例化一个对象,而工厂模式实例化对象直接调用函数即可。
要创建person的新实例,必须使用new操作符。用这种方式调用构造函数实际上会经历以下四个步骤:
1.创建一个新对象;2.将构造函数的作用域赋给新对象(因此this就指向了这个新对象);3.为这个新对象添加属性;4.返回新对象。
这种方法虽然好用,但也不是没有问题。例如当你需要创建100个person,这100个对象都是单独的个体,它们之间的私有属性是不相等的,当创建100个这样的对象时,加入一个对象中有一个方法,那创建100个对象就要创建100个方法,但是这些方法都是一样的功能,就没有这个必要去浪费内存空间。所以开始就有了下面的方法五了。
方法五:原型模式创建对象
原型模式有一个强大的功能就是可以实现数据共享,从而节省空间,比如上面的100个对象有100个功能一样的方法,那我完全可以让这100个对象共用一个方法。
1 <script> 2 function person(name,age) 3 { 4 this.name=name; 5 this.age=age; 6 } 7 person.prototype.eat=function() 8 { 9 console.log("吃东西"); 10 } 11 var p1=new person("小米",30); 12 var p2=new person("小明",20); 13 </script>
如上需要共享的数据就可以写在原型对象(prototype)中,不需要共享的数据写在构造函数person中,
以后用new person创建的每一个对象,都可以享用到prototype里面的属性和方法,而构造函数person里的属性和方法则根据创建对象时传入的参数不同来决定。
1 <script> 2 2 function student(name,age,sex){ 3 3 this.name=name; 4 4 this.age=age; 5 5 this.sex=sex; 6 6 } 7 7 student.prototype={ 8 8 constructor:student, 9 9 height:"180", 10 10 weight:"55kg", 11 11 study:function(){ 12 12 console.log("学习好开心"); 13 13 }, 14 14 eat:function(){ 15 15 console.log("好好吃"); 16 16 } 17 17 }; 18 18 var stu=new student("张飞",20,"男"); 19 19 stu.eat();//好好吃 20 20 stu.study();//学习好开心 21 21 </script>
关于构造函数、原型对象、实例对象的指向关系,表述如下:
构造函数可以实例化对象;
构造函数中有一个属性叫prototype,是构造函数的原型对象;
构造函数的原型对象(prototype)中有一个constructor构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数;
实例对象的隐含属性(__proto__)指向的是该构造函数创造的原型对象;
以上资料,部分参考自《javascript高级语言程序设计(第三版)》,如有错误,并无误导之意,请前辈不吝指出!感谢!