zoukankan      html  css  js  c++  java
  • js面向对象之创建对象

    工厂模式

    function createPerson(name,age,job){
        var o  = new Object();
        o.name = name;
        o.age = age;
        o.job = job;
        o.sayName = function(){
            alert(this.name);
        }
        return o;
    }
    
    var person1 = createPerson('zy1',28,'new worker');
    var person2 = createPerson('zy2',29,'new worker2');

    工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别问题(即怎么样知道一个对象的类型)。因为全部都是Object,不像Date、Array等,因此出现了构造函数模式。

     构造函数模式

    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = function(){
            alert(this.name);
        }
    }
    var person1 = new Person('zy1',28,'new worker');
    var person2 = new Person('zy2',29,'new worker2');

    构造函数模式与工厂模式比较有以下不同

    • 没有显式地创建对象
    • 直接将属性和方法赋给this对象
    • 没有return语句

    这种方法创建的对象都有一个constructor属性,此例中指向Person,即 person1.constructor == Person


    构造函数与普通函数的区别就在于调用的方式,即new出来的。如果不通过new操作,那它跟普通函数没有什么两样

    构造函数的缺点:

    构造函数中每个方法都要在每个实例上重新创建一遍,如果上面的person1和person2方法中sayName(),不是同一个Function实例。因为函数是对象,即每定义一个函数,也就是实例化一个对象。

    即上面的等价 this.sayName = new Function("alert(this.name)")


    上面的的方法也可以改成

    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.sayName = sayName
    }
    function sayName(){
        alert(this.name)
    }

    但是这样sayName()就成为全局函数,很不好,所以引出下面的模式

    原型模式

    关于原型的具体见http://www.cnblogs.com/myzy/p/6083141.html这里就不解释了

    使用原型好处是可以让所有对象实例共享它所包含的属性和方法。

    function Person(){}
      Person.prototype.name = 'zy';
      Person.prototype.age='29';
      Person.sayName = function(){
          alert(this.name);
      }
    var person1 = new Person();
    var person2 = new Person();
    alert(person1.sayName == person2.sayName) //true

    更简单的原型语法

    function Person(){
    }
    Person.prototype = {
        name:'zy',
        contructor:Person,
        age:29,
        sayName:function(){
            alert(this.name);
        }
    }

    注意,这里重新设置了contructor.因这如果不加contructor,这样方式创建的新对象,构造函数不再指向Person

    缺点:如果一个实例修改了原型中的属性值,那么其他实例中这个属性值也会改变。

    组合使用构造函数模式和原型模式

    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.friends=['a','b'];
    }
    Person.prototype = {
        contructor:Person,
        sayName:function(){
            alert(this.name);
        }
    }

    这种模式是使用最广泛的方法。

    动态原型模式

    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.friends=['a','b'];
        if(typeof this.sayName != 'function'){
            alert(this.name);
        }
    }

    其中if语句可以是初始化之后应该存在的任何属性或方法,不必用一大堆if语句检查每个语句和每个方法,只要检查其中一个即可。

    寄生构造函数模式

    function Person(name,age,job){
        var o  = new Object();
        o.name = name;
        o.age = age;
        o.job = job;
        o.sayName = function(){
            alert(this.name);
        }
        return o;
    }
    
    var person1 = new Person('zy1',28,'new worker');

    这里了new操作符并把使用的包装函数叫做构造函数之外,这个模式和工厂模式其实是一模一样的。

    稳妥构造函数模式

    function Person(name,age,job){
        var o  = new Object();
        o.sayName = function(){
            alert(name);
        }
        return o;
    }
    
    var person1 = Person('zy1',28,'new worker');

    这种方法不引用this,new。这种模式提供的这种安全性,使得它非常适合在某些安全执行环境。

  • 相关阅读:
    Vue 开发常见问题集锦
    java lambda 所有列求和
    如何解决Bat脚本中包含中文,运行乱码
    Failed to parse multipart servlet request; nested exception is java.io.IOException: The temporary upload location [/tmp/tomcat.1428942566812653608
    mysql的时区错误问题,The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one
    Error:Execution failed for task ':app:compileDebugJavaWithJavac'
    com.android.ddmlib.adbcommandrejectedexception:未经授权的设备。
    jar包编译成 dex
    apk 查看sha1签名
    Mybatis invalid comparison: java.util.Date and java.lang.String
  • 原文地址:https://www.cnblogs.com/myzy/p/6150378.html
Copyright © 2011-2022 走看看