zoukankan      html  css  js  c++  java
  • 创建对象的5种方式

    创建对象的方式有5种

    1. 工厂方法——使用new Object创建对象并添加相关属性
    2. 构造函数——来定义类(原型对象)
    3. 原型模式——使用prototype
    4. 混合模式——构造函数和原型模式的混合方式(推荐
    5. 动态原型方式
     
    //1,工厂模式
    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;   //需要把o返回
    }
    var person1 = createPerson("wang",22,"Engineer");
    alert(person1.name);
    //可以无数次调用这个函数,虽然解决了创建多个相似对象的问题,却无法知道一个对象的类型
    
    //2,构造函数模式
    function Person(name,age,job) {
    this.name  = name;
    this.age = age;
    this.job = job;
    this.sayName = function () {
    alert(this.name);
         }
     }
    var person2 = new Person("leo",22,"Engineer");
    alert(person2.age);
    //构造函数名首字母大写,表示它可以用来创建对象;
    //创建Person的新实例,需要new操作符;
    //创建自定义的构造函数可以把它的实例标识为一种特定的类型(优于工厂模式);
    //缺点:每个方法都要在每个实例上重新创建一遍
    
    //3、原型模式
    function Person() { }  //构造函数是一个空函数
    Person.prototype.name = "wang";
    Person.prototype.age = 22;
    Person.prototype.friends = ["aaa","bbb"];
    Person.prototype.sayName = function () {
    alert(this.name);
     };
    var person1 = new Person();
     person1.sayName();
    var person2 = new Person();
     person2.sayName();
    alert(person1.sayName == person2.sayName);//true
     //原型模式的好处是可以让所有的对象实例共享它所包含的属性和方法
    
    person1.name = "leo";
    //通过对象实例同名的属性,只可以屏蔽原型中的那个属性,
    //原理是:先找对象实例里的属性值,若找不到,则再找原型里的属性值
    alert(person1.name);  //leo
     //使用hasOwnProperty()方法。可以方便的判断什么时候访问的的实例属性(true),什么时候是原型属性
    
    person1.friends.push("ccc");
    alert(person1.friends);  //aaa,bbb,ccc
    alert(person2.friends);  //aaa,bbb,ccc
     //缺点:由于原型中的所有属性的被它的很多实例共享的,如果包含引用类型(例如数组)值的属性时,
    //改变某个实例的该属性,另外的实例的这个属性也会变,因为他们都指向Person.proptotype
    
     //4,构造函数和原型模式的混合模式
    function Person(name,age,job) {
    this.name = name;
    this.age = age;
    this.job = job;
    this.friends = ["aaa","bbb"];
     }
    Person.prototype.sayName = function () {
    alert(this.name);
     }
    var person1 = new Person("wang",23,"engineer");
    var person2 = new Person("leo",23,"teacher");
     person1.friends.push("ccc");
    alert(person1.friends);  //aaa,bbb,ccc
    alert(person2.friends);  //aaa,bbb
    alert(person1.friends === person2.friends); //false
    alert(person1.sayName === person2.sayName); //true
     //每个实例都会有自己的一份实例属性的副本,但同时有共享对方法的引用,最大限度节省内存;
    //实例属性都是在构造函数中定义的(改变不会影响到其他的实例),而所有实例共享的属性constructor和方法sayName()则是在原型中定义的
    
    //5,动态原型模式
    function Person(name,age,job) {
    this.name = name;
    this.age = age;
    if(typeof this.sayName != "function"){
    Person.prototype.sayName = function () {
    alert(this.name);
             }
         }
     }
    var friend = new Person("wang",22,"coder");
     friend.sayName();
    //只有在sayName()方法不存在时才会将它添加到原型中,这段代码只会在初次调用构造函数时才会执行
    
  • 相关阅读:
    ffmpeg rtmp推流 视频转码
    java日志发展史 log4j slf4j log4j2 jul jcl 日志和各种桥接包的关系
    nginx stream 流转发,可以转发rtmp、mysql访问流,转发rtmp、jdbc请求
    java web http 转https 通过nginx代理访问
    linux 服务器磁盘挂载
    novnc 通过websockify代理 配置多点访问
    linux 文件服务 minio 安装部署配置
    AOP实现原理,手写aop
    java 泛型
    JAVA反射getGenericSuperclass()用法
  • 原文地址:https://www.cnblogs.com/easonw/p/6072784.html
Copyright © 2011-2022 走看看