zoukankan      html  css  js  c++  java
  • 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>
    View Code

    运行结果:

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

  • 相关阅读:
    [转]vc中socket编程步骤
    [转载]使用命名管道实现进程间通信
    换肤软件摘要
    3D 专业词汇 (转)
    如何从 Microsoft DirectShow 筛选器图形获取数据(转)
    “人大艺术学院”“赵雅芝中文网”等网站被挂马 狼人:
    微软将发布5月安全漏洞补丁 修补PPT 狼人:
    专家提醒:网络挂马借“海运女”传播 狼人:
    黑客借“甲型流感”传毒 挂马疾病预防控制中心网站 狼人:
    黑客称攻破乔布斯亚马逊网站账户 欲售相关信息 狼人:
  • 原文地址:https://www.cnblogs.com/why-not-try/p/9097563.html
Copyright © 2011-2022 走看看