前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript中创建对象的几种模式

JavaScript中创建对象的几种模式

作者头像
用户1149564
发布2018-07-31 16:36:11
1.2K0
发布2018-07-31 16:36:11
举报
文章被收录于专栏:Micro_awake web

代码如下:

代码语言:javascript
复制
  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>创建对象的模式</title>
  6     <meta name="viewport" content="width=device-width, initial-scale=1">
  7     <!--<link rel="stylesheet" type="text/css" href="main.css"/>-->
  8     <!--<script src="main.js"></script>-->
  9 </head>
 10 <body>
 11 <script>
 12     //js中没有类的概念,所以开发人员使用函数来封装特定接口从而创建对象
 13     //1.工厂模式,解决了创建多个相似对象的问题,但是没有解决对象识别问题
 14     function t1(name,age,sex){
 15         var o={};
 16         o.name=name;
 17         o.age=age;
 18         o.sex=sex;
 19         return o;
 20     };
 21     var p1=t1('张三',21,'male');
 22     var p2=t1('Alice',23,'female');
 23     console.log(p1,p2);
 24     console.log(typeof p1,typeof p2);
 25 
 26 //    2.构造函数模式
 27     function T2(name,age,sex){
 28         this.name=name;
 29         this.age=age;
 30         this.sex=sex;
 31         this.showInfo=function(){
 32             console.log(this.name+' '+this.age+' '+this.sex);
 33         }
 34     }
 35     var p3=new T2('李四',25,'male');
 36     var p4=new T2('Mary',22,'female');
 37     //此时对象的constructor是用来标识对象类型的
 38     console.log(p3,p4,p3.constructor===T2,p4.constructor===T2);
 39     console.log(p3 instanceof Object,p3 instanceof T2);
 40 
 41     //如果将构造函数作为普通函数调用,那么属性和方法都被添加到全局对象,这里是window
 42     T2('ww',29,'male');
 43     console.log(window.name,age,sex);
 44 
 45 //    构造函数模式存在的缺陷:构造函数里面的方法(上面指showInfo)不是共享的,即每次的showInfo不相同
 46     console.log(p3.showInfo===p4.showInfo);
 47 
 48 //    3.原型模式
 49     function T3(){
 50     }
 51     T3.prototype.name='Aya';
 52     T3.prototype.age=100;
 53     T3.prototype.showInfo=function(){
 54         console.log(this.name);
 55     };
 56 
 57     var p5=new T3();
 58     p5.showInfo();
 59     var p6=new T3();
 60     p6.showInfo();
 61     console.log(p5.showInfo===p6.showInfo);
 62 //    实例中的属性或方法会覆盖原型中的属性或方法
 63     p5.name='xiaoming';
 64     p5.showInfo();
 65     delete p5.name;
 66     p5.showInfo();
 67 //    js引擎对属性的寻找都是从下往上追溯的
 68 
 69 //    使用hasOwnProperty()可以检测属性在实例上,还是在原型上
 70     p6.name='nicai';
 71     console.log(p6.hasOwnProperty('name'));
 72 //    使用in,属性在原型上或者实例上,均返回true
 73     console.log('name' in p5,'name' in p6);
 74 
 75 //    所以当hasOwnProperty()返回false,而in返回true,那么属性位于原型上
 76     if (!p5.hasOwnProperty('name') && 'name' in p5){
 77         console.log('name属性在原型上');
 78     }
 79 
 80 //    原型模式更直观的可以写为下面形式:
 81     function T4(){}
 82     T4.prototype={
 83         name:'abc',
 84         age:100,
 85         sayHi:function(){
 86             console.log(this.name);
 87         }
 88     }
 89 //    原型模式存在的问题:1.所有属性初始值一样;2.最大的问题,当含有引用类型时,一个实例对象的修改会导致其它实例对象也跟着修改
 90     function T5(){}
 91     T5.prototype={
 92         constructor:T5,
 93         name:'abc',
 94         age:100,
 95         arr:[1,2,3]
 96     }
 97     var p7=new T5();
 98     var p8=new T5();
 99     //所有实例对象的引用类型会相应变化
100     p7.arr.unshift(0);
101     //实例对象的基本类型倒不影响
102     p7.name='Bob';
103     console.log(p7.arr,p8.arr,p7.name,p8.name);
104 
105 //    4.组合使用构造函数模式与原型模式
106 //    是目前在ECMAScript使用最广泛、认可度最高的一种创建自定义类型的方法
107     function Person(name,age){
108         this.name=name;
109         this.age=age;
110         this.friends=['Alice','Bob'];
111     }
112     Person.prototype={
113         constructor:Person,
114         sayHello:function(){
115             console.log(this.name);
116         }
117 
118     };
119     var per1=new Person('Apple',1000);
120     var per2=new Person('Blue',10);
121     per1.friends.push('cat');
122     console.log(per1.friends,per2.friends);
123     console.log(per1.sayHello===per2.sayHello);
124 
125 //    5.动态原型模式
126     function Person1(name,age){
127         this.name=name;
128         this.age=age;
129         if(typeof this.sayHello !== 'function'){
130             Person1.prototype.sayHello=function(){
131                 console.log(this.name);
132             }
133         }
134     }
135     var per3=new Person1('Bill',111);
136     console.log(per3);
137 
138 //    6.寄生(parasitic)构造函数模式
139 //    其实与工厂模式一样,除了使用构造函数和new操作符
140     function Person2(name,age){
141         var o={};
142         o.name=name;
143         o.age=age;
144         return o;
145     }
146     var per4=new Person2('Egg',100);
147 
148 //    7.稳妥(durable)构造函数
149 //    与寄生构造函数模式类似,但两处不同点:1.新创建对象的实例方法不使用this 2.不使用new 调用构造函数
150 //    稳妥构造函数适合在某些安全环境下
151     function Test3(age){
152         var o={};
153         o.showName=function(){
154             console.log(age);
155         };
156         return o;
157     }
158     var per5=Test3(100);
159     console.log(per5);
160 </script>
161 </body>
162 </html>

运行结果:

参考<<JavaScript高级程序语言设计>>

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-05-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档