zoukankan      html  css  js  c++  java
  • Javascript高级程序设计——面向对象之创建对象

    对象创建方法:

    1. 工厂方法
    2. 构造函数模式
    3. 原型模式
    4. 组合构造函数和原型模式
    5. 寄生构造函数模式
    6. 问题构造函数模式

    工厂模式:

    function Person(name, age){
        var obj = new Object();        //创建对象
        
        obj.name = name;               //添加方法、属性
        obj.age = age;
        obj.sayName = function(){
            alert(this.name);
        }
        
        return obj;                    //返回对象
    }
    var people = Person("yangxunwu", 24);

    缺点:返回的对象全部是object的实例,无法完成对象识别

    构造函数模式:

    function Person(name, age){
        this.name = name;            //添加方法、属性
        this.age = age;
        this.sayName = function(){
            alert(this.name);
        };
    }
    
    var people = new Person("yangxunwu", 24);
    //注意多了new操作

     构造函数创建实例时,必须用new操作符,经历四个步骤:

    1. 创建对象
    2. 将构造函数的作用域赋给对象。(this指向新对象)
    3. 执行构造函数代码。
    4. 返回新对象。

     缺点:虽然创建的实例可以通过instanceof操作符 来识别,但函数无法复用

    原型模式:

    function Person(){                      //创建空的构造函数
    }
    
    Person.prototype.age = age;                //构造函数原型上添加属性和方法,达到函数复用
    Person.prototype.sayName = function(){
        alert(Person.prototype.name);
    };
    
    var people = new Person();

      当创建一个新函数时,会自动根据特定规则为函数创建prototype属性,这个属性是一个指针指向函数的原型对象,

    原型对象会自动的获得一个constructor属性,这也是一个指针,指向拥有这个prototype属性的函数

    Pesson.prototype.constructor = Person

      创建自定义构造函数后,其原型对象自动获得constructor属性,其他的方法都从object继承。当通过构造函数创建

    一个新实例后,实例自动获得一个指针,指向构造函数的原型对象,一般名称是__proto__属性

      当代码读取某个属性时,一般会经过两个过程一个是在实例上搜索属性,搜索不到就通过__proto__属性到原型对象上搜索

    通过hasOwnProperty()方法,可以检测一个属性是存在实例中还是原型中,实例中返回true。

      原型对象上的属性可以让所有实例共享,但是当属性为引用类型时就会容易产生问题

    function Person(){
    }
    
    Person.prototype.names = ["yang", "zhang"];
    
    var people1 = new Person();
    var people2 = new Person();
    
    people1.names   //["yang", "zhang"]
    people2.names   //["yang", "zhang"]
    
    people1.names.push("test");   //因为属性共享,而且是引用类型,所以names改变了
    
    people1.names   //["yang", "zhang", "test"]
    people1.names   //["yang", "zhang", "test"]

    实例一般应该有自己的全部属性,这里没有

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

    function Person(name, age){                //构造函数继承的属性是独有的
        this.name = name;
        this.age = age;
        this.friends = ["yang", "zhang"];
    }
    
    Person.prototype.sayName = function(){    //通过原型模式来共享方法
        alert(this.name);
    }
    
    //创建实例,实例不共享属性,共享方法
    var people1 = new Person("yangxunwu", 24);
    var people2 = new Person("hexiaoming", 6);
    
    //访问引用类型
    people1.friends;          //["yang", "zhang"]
    people1.friends;          //["yang", "zhang"]
    
    //为添加元素
    people1.friends.push("wang");
    
    people1.friends;          //["yang", "zhang","wang"] 元素被添加到people1的属性中,因为构造函数不共享属性
    people1.friends;          //["yang", "zhang"]
    
    people1.sayName === people2.sayName    //true。共享方法

    动态原型模式:

    function Person(name, age){                //动态原型模式
        this.name = name;
        this.age = age;
        this.friends = ["yang", "zhang"];
        
        if(Person.prototype.sayName != "function"){    //动态加载,只在第一次添加原型方法
            Person.prototype.sayName = function(){    
            alert(this.name);
            }
        };
    }

    只在第一次调用构造函数时执行,之后原型已经完成初始化。

    寄生构造函数模式:

    function Person(name, age){                
        var obj = new Object();                    //生成一个Objdetde对象
        
        obj.name = name;
        obj.age = age;
        obj.sayName = functon(){
            alert(this.name);
        }
        
        return obj;                                //返回的一直是Object的对象。
    }
    
    var people = new Person("yangxunwu", 24);    //与工厂模式的区别,坑
    people.sayName();      //yangxunwu

    返回的对象与构造函数或者构造函数的原型没关系,而且返回的一直是Object类型。只是把外部干的事放到内部干。

    稳妥构造函数:

    function Person(name, age){                
        var obj = new Object();
        //定义私有变量和函数
        obj.doSomething = function(){
            alert(name);                   //定义可以访问私有变量和函数的方法,没有引用this
        }
        
        return obj;                        //返回对象,现在只有这个对象可以访问这些私有变量和函数。
    }
    
    var people = Person("yangxunwu", 24);  //没使用new
    people.sayName();      //yangxunwu

    稳妥构造就是没有公共的属性,不引用this,防止数据被其他应用程序破坏。稳妥构造函数与寄生构造函数不同:

    1. 新创建的对象方法不引用this
    2. 不使用new操作符来调用构造函数。
  • 相关阅读:
    用代理模式 保持用户关闭链接的习惯
    jdbc 链接池的优化
    jdbc 链接池
    xml 操作
    互联网时代常用网站资源整理汇总(一直在完善中)
    快速读懂机器学习(附送详细学习资源)
    快速读懂机器学习(附送详细学习资源)
    常见网络命令之traceroute命令一起其他常用命令
    常见网络命令之traceroute命令一起其他常用命令
    Java案例之士兵作战功能实现
  • 原文地址:https://www.cnblogs.com/yangxunwu1992/p/4780426.html
Copyright © 2011-2022 走看看